Jest测试时mock函数调用次数始终为0怎么办?
在测试React组件时遇到了奇怪的问题。我用jest.fn()模拟了一个handleClick函数,但测试时expect(mockFn.mock.calls.length).toBe(1)一直报错说实际是0。组件里确实绑定了这个函数,测试代码也用了fireEvent.click…
我已经尝试过在测试最后加了waitFor(),也确认过事件绑定没有错。但控制台打印mockFn的calls数组始终是空的。这是不是和React的StrictMode有关?或者是不是应该用useEffect来手动触发?
组件代码:
const MyButton = ({ onClick }) => {
return <button onClick={() => onClick('test')}>Click me</button>;
};
测试代码报错部分:
test('should call handleClick', async () => {
const mockFn = jest.fn();
render(<MyButton onClick={mockFn} />);
fireEvent.click(screen.getByText('Click me'));
await waitFor(() => expect(mockFn).toHaveBeenCalled());
});
按照官方文档的说法,StrictMode会在开发模式下故意触发两次渲染,目的是帮助开发者发现潜在的副作用问题。不过这确实会给测试带来一些麻烦。
解决方法其实很简单,标准写法是在测试环境中禁用StrictMode。如果你用的是create-react-app,可以在
src/setupTests.js里加一行代码:或者更推荐的做法是直接修改测试用例,确保事件绑定正确:
这里有几个关键点:第一,不需要用
async/await和waitFor,因为事件触发是同步的;第二,要验证参数传递是否正确;第三,确保测试环境和实际运行环境一致。说实话,React的这个行为确实让人头疼,特别是对新手来说。我之前也被坑过好几次,后来严格按照官方文档的最佳实践来写测试,类似的问题就少了很多。记得多看看React Testing Library的文档,他们对这些常见问题都有详细的说明。