簡體   English   中英

如何使用 React 測試庫將服務中的數據模擬為鈎子?

[英]How to mock data from service as hook with React Testing Library?

我開始使用React 測試庫對 React 應用程序進行測試,但我正在努力模擬使用Hook作為服務進行 API 調用的組件中的數據。

我的組件只是一個功能組件,沒有什么特別之處:

import React, { useEffect, useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import Skeleton from '@material-ui/lab/Skeleton'

import usePanelClient from '../../../clients/PanelClient/usePanelClient'
import useUtils from '../../../hooks/useUtils'
import IconFile from '../../../assets/img/panel/ico-file.svg'
import IconExclamation from '../../../assets/img/panel/ico-exclamation.svg'
import IconPause from '../../../assets/img/panel/awesome-pause-circle.svg'
import './PendingAwards.scss'

const PendingAwards = () => {
  const pendingAwardsRef = useRef(null)
  const location = useLocation()

  const [loading, setLoading] = useState(true)
  const [pendingAwards, setPendingAwards] = useState({})
  const panelClient = usePanelClient()
  const { formatCurrency } = useUtils()

  useEffect(() => {
    panelClient()
      .getPendingAwards()
      .then((response) => {
        setLoading(false)
        setPendingAwards(response.data)
      })
  }, [panelClient])

  useEffect(() => {
    const searchParams = new URLSearchParams(location.search)
    if (searchParams.get('scrollTo') === 'pendingAwards') {
      window.scrollTo({
        top: 0,
        behavior: 'smooth',
      })
    }
  }, [location])

  return (
    <div
      id="pendingAwards"
      className="pending-awards-container"
      ref={pendingAwardsRef}
    >
      <span className="pending-awards-container__title">Prêmios Pendentes</span>
      {loading && (
        <div className="skeleton-box">
          <Skeleton width="100%" height="70px" />
          <Skeleton width="100%" height="70px" />
        </div>
      )}

      {!loading && (
        <div className="pending-awards-values">
          <div className="pending-awards-container__quantity">
            <div className="pending-awards-container__quantity-container">
              <span className="pending-awards-container__quantity-container-title">
                Quantidade
              </span>
              <span className="pending-awards-container__quantity-container-content">
                <div className="pending-awards-container__quantity-container-content__icon-box">
                  <img src={IconFile} alt="Ícone de arquivo" />
                </div>
                {pendingAwards.quantity ? pendingAwards.quantity : '0'}
              </span>
            </div>
          </div>

          <div className="pending-awards-container__amount">
            <div className="pending-awards-container__amount-container">
              <span className="pending-awards-container__amount-container-title">
                Valor Pendente
              </span>
              <span className="pending-awards-container__amount-container-content">
                <div className="pending-awards-container__amount-container-content__icon-box">
                  <img src={IconPause} alt="Ícone Pause" />
                </div>
                {pendingAwards.amount
                  ? formatCurrency(pendingAwards.amount)
                  : 'R$ 0,00'}
              </span>
            </div>
          </div>
          <div className="pending-awards-container__commission">
            <div className="pending-awards-container__commission-container">
              <span className="pending-awards-container__commission-container-title">
                Comissão Pendente
              </span>
              <span className="pending-awards-container__commission-container-content">
                <div className="pending-awards-container__commission-container-content__icon-box">
                  <img src={IconExclamation} alt="Ícone exclamação" />
                </div>
                {pendingAwards.commission
                  ? formatCurrency(pendingAwards.commission)
                  : 'R$ 0,00'}
              </span>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}
export default PendingAwards

我進行 API 調用的服務是這樣編寫的:

import { useCallback } from 'react'
import axios from 'axios'

const usePanelClient = () => {
  const getQuotationCard = useCallback(() => axios.get('/api/cards/quotation'), [])
  const getCommissionCard = useCallback(() => axios.get('/api/cards/commission'), [])
  const getPendingAwards = useCallback(() => axios.get('/api/premium/pending'), [])

  return useCallback(() => ({
    getQuotationCard,
    getCommissionCard,
    getPendingAwards,
  }), [
    getQuotationCard,
    getCommissionCard,
    getPendingAwards,
  ])
}

export default usePanelClient

在我當前的測試中,我嘗試像這樣模擬鈎子,但沒有成功:

import React from 'react'
import { render } from '@testing-library/react'
import { Router } from 'react-router-dom'
import { createMemoryHistory } from 'history'

import PendingAwards from './PendingAwards'

describe('PendingAwards Component', () => {
  beforeEach(() => {
    jest.mock('../../../clients/PanelClient/usePanelClient', () => {
      const mockData = {
        quantity: 820,
        amount: 26681086.12,
        commission: 5528957.841628,
      }
      return {
        getPendingAwards: jest.fn(() => Promise.resolve(mockData)),
      }
    })
  })

  it('should render the PendingAwards', () => {
    const history = createMemoryHistory()
    history.push = jest.fn()
    const { container } = render(
      <Router history={history}>
        <PendingAwards />
      </Router>,
    )
    expect(container).toBeInTheDocument()
  })

  it('should render the PendingAwards', () => {
    const history = createMemoryHistory()
    history.push({
      search: '&scrollTo=pendingAwards',
    })
    window.scrollTo = jest.fn()
    render(
      <Router history={history}>
        <PendingAwards />
      </Router>,
    )
    expect(window.scrollTo).toHaveBeenCalledWith({ behavior: 'smooth', top: 0 })
  })
})

有人可以幫我解決這個問題嗎? 我不覺得這是什么難事,但我已經嘗試了幾件事,似乎沒有什么能解決它。

提前致謝。

您必須在模塊的頂層調用jest.mock並且要使用默認導出__esModule: true ES6 模塊,您應該使用__esModule: true

jest.mock('../../../clients/PanelClient/usePanelClient', () => {
  const mockData = {
    quantity: 820,
    amount: 26681086.12,
    commission: 5528957.841628,
  }
  return {
    __esModule: true,
    default: ()=> ({
      getPendingAwards: jest.fn(() => Promise.resolve({data: mockData})),
    }),
}});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM