Jest模拟API调用无返回数据,React自定义Hook测试失败
问题排查与解决方案
核心问题分析
测试失败主要源于以下几个关键点:
- Mock函数返回值不符合要求:
getMonitoringData是异步函数,实际返回Promise<MonitoringData[]>,但你的mock直接返回了普通数组,而非Promise,导致await getMonitoringData()执行时抛出异常。 - 未等待异步状态更新:React的
setMonitoringData是异步操作,测试中render后直接结束,不会等待状态更新完成,无法捕获到最终的状态变化。 - 未控制
isSuperUser状态:如果useFundRaising中isSuperUser默认值为true,测试会进入if分支,而非你要验证的else分支。 - 缺少断言逻辑:当前测试仅做了渲染操作,没有验证结果是否符合预期,无法确认目标逻辑是否正确执行。
修正后的测试代码
jest.mock('@api/Monitoring', () => ({ // 修正:返回Promise包裹的模拟数据,匹配原函数的异步返回类型 getMonitoringData: () => Promise.resolve([mockedData]), })); describe('useFundRaising custom hook', () => { it('should load initial monitoring data and select default product when not super user', async () => { // 确保isSuperUser为false(根据hook的参数传递方式调整,比如props/context) function TestComponent() { const { monitoringData, selectedProduct } = useFundRaising({ isSuperUser: false }); return ( <div> <span data-testid="monitoring-data">{JSON.stringify(monitoringData)}</span> <span data-testid="selected-product">{selectedProduct?.name}</span> </div> ); } const { getByTestId, waitFor } = render(<TestComponent />); // 等待异步状态更新完成,同时添加断言验证结果 await waitFor(() => { expect(getByTestId('monitoring-data').textContent).toBe(JSON.stringify([mockedData])); expect(getByTestId('selected-product').textContent).toBe(mockedData.product?.name); }); }); });
额外优化建议
- 验证排序逻辑:构造包含多个产品的模拟数据,断言排序后的结果符合
a.product?.name升序的要求。 - 处理
intermediaryId参数:如果intermediaryId需要特定值,在测试中传入正确参数,避免API请求路径异常。 - 覆盖错误场景:添加测试用例,模拟
getMonitoringData返回null或抛出错误,验证hook的容错逻辑。
内容的提问来源于stack exchange,提问作者Aessandro
相关产品推荐
相关产品推荐

