【发布时间】:2025-12-19 17:25:12
【问题描述】:
我开始使用 React 测试库 为 React 应用程序进行测试,但我正在努力模拟组件中的数据,该组件使用 Hook 进行 API 调用 strong> 作为服务。
我的组件只是一个功能组件,没什么特别的:
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 移到 beforeEach 块之外。我看到的另一个问题是模拟数据应该有一个名为 data 的属性,因为它是您在组件中所期望的 (response.data)
-
@lissettdm 我会试着改成那个,你
-
我试过这样做,但似乎没有用:
jest.mock('../../../clients/PanelClient/usePanelClient', () => { const mockData = { quantity: 820, amount: 26681086.12, commission: 5528957.841628, } return { getPendingAwards: jest.fn(() => Promise.resolve({ data: mockData })), } })我也收到此错误:UnhandledPromiseRejectionWarning: Error: Network Error
标签: reactjs jestjs react-testing-library