使用React Testing Library/Jest mock axios post请求时报错如何解决
报错根因
你的业务代码中使用的是axios({ method: 'post', ... })的函数调用形式,但__mocks__/axios.js中默认导出的是仅包含post方法的普通对象,没有将axios模拟为可调用的函数,因此运行时触发「默认导出不是函数」的类型错误。
修复步骤
1. 修正mock文件的导出逻辑
原生axios本身是一个可调用函数,同时身上挂载了post/get等别名方法,你的mock需要兼容这两种调用形式:
// __mocks__/axios.js // 首先把axios模拟为可调用的函数 const mockAxios = jest.fn(() => Promise.resolve({ data: {} })); // 给mock函数挂载所有用到的axios别名方法 mockAxios.post = jest.fn(() => Promise.resolve({ data: {} })); mockAxios.get = jest.fn(() => Promise.resolve({ data: {} })); mockAxios.put = jest.fn(() => Promise.resolve({ data: {} })); mockAxios.delete = jest.fn(() => Promise.resolve({ data: {} })); export default mockAxios;
2. 调整测试用例的mock设置时机和对象
你当前是在点击Yes按钮之后才设置mock返回值,此时点击事件触发的axios请求已经执行,mock规则还未生效;另外由于你的业务代码用的是axios()直接调用的形式,不需要给post方法设置返回值,直接给mock的axios函数设置即可:
// 测试用例中相关逻辑调整如下 const completeButton = batchList.getByText('Complete'); fireEvent.click(completeButton); const yesButton = batchList.getByText('Yes'); expect(yesButton).toBeInTheDocument(); // 先设置mock返回值 const data = { msg: 'fail', invalidBatchNumbers: ['987654', '445566'], }; mockedAxios.mockResolvedValueOnce({ data: data }); // 再触发点击发送请求 fireEvent.click(yesButton); await waitFor(() => { expect(batchList.getByText('987654')).toHaveClass('invalid'); expect(batchList.getByText('261010')).toHaveClass('valid'); });
可选优化(更推荐)
你已经在测试中引入了MSW,完全可以直接用MSW拦截接口请求,不需要手动mock axios,更贴近真实运行逻辑,也不需要处理不同axios调用形式的兼容问题。
内容的提问来源于stack exchange,提问作者dmikester1
相关产品推荐
相关产品推荐

