You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Jest测试时expect(jest.fn()).toHaveBeenCalledWith调用次数为0如何解决?

问题根因

你遇到的两个报错存在直接关联:先触发的TypeError: Cannot read property 'push' of undefined导致history.push逻辑根本无法执行,自然会出现调用次数为0的断言失败。具体问题和修复方案如下:


1. 修复push is undefined报错

该问题是由jest.mock的变量提升机制导致的:

  • jest.mock会被Jest自动提升到文件最顶部执行,此时你在外部声明的mockHistoryPush还未初始化,所以useHistory返回的对象里push是undefined。

修复后的mock写法:

// 把mock方法定义放到jest.mock内部,避免变量提升导致的未定义
jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useHistory: () => ({
    push: jest.fn(),
  }),
}));

测试用例内获取mock实例:

it('should render card with data when clicked for *', async () => {
  // 从mock的react-router-dom中获取push的mock实例
  const mockHistoryPush = require('react-router-dom').useHistory().push;
  SearchWrapper = mount(<CustomerSearch />);
  // 后续逻辑
})

2. 修复调用次数为0的问题

解决完push的定义问题后,如果还是断言失败,按以下步骤排查:

  • 先确认你已经给表单输入框赋值为*:测试用例中直接点击提交按钮不会自动填充表单值,需要先模拟输入操作,示例:
    // 替换成你实际的输入框选择器
    SearchWrapper.find('input#searchInput').simulate('change', { target: { value: '*' } });
    
  • 确认你已经mock了提交触发的API请求:需要让接口返回searchResult.data长度大于1的结果,否则不会走到跳转分支。可以在测试前先打桩接口返回值。
  • 增加异步等待逻辑,确保所有异步任务执行完成后再断言,推荐用waitFor包裹断言:
    import { waitFor } from '@testing-library/react';
    
    // 替换原有断言
    await waitFor(() => {
      expect(mockHistoryPush).toHaveBeenCalledWith(locationStateMock2);
    })
    
  • 可以通过校验console.log('length greater than 1')是否在测试运行时输出,确认逻辑是否走到了跳转分支。

内容的提问来源于stack exchange,提问作者pavan sai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 13:57:04