使用jest和testing-library测试React组件多axios调用时如何匹配URL
问题解决方法
第一步:确认axios mock是否正确生效
在测试文件最顶部(所有import语句之前)添加如下代码,确保组件中引入的axios被替换为mock版本:
jest.mock('axios', () => require('jest-mock-axios'));
绝大多数情况下url参数为空是因为mock未正确替换真实axios,导致写好的mockImplementation完全没有触发。
第二步:排查调用方式不匹配问题
有两种常见的调用不匹配场景会导致拿不到url:
- 如果你组件中使用的是
axios({ method: 'GET', url: 'xxx' })传入配置对象的写法,而非axios.get(url)写法,此时你mockmockAxios.get不会被触发,需要直接mockmockAxios本身:
mockAxios.mockImplementation((config) => { console.log("拿到的完整请求配置", config); const url = config.url; switch (url) { case "/companies/123/activity": return Promise.resolve({ data: [] }); case "/activity/events": return Promise.resolve({ data: [] }); case "/companies/123/activity/users": return Promise.resolve({ data: [] }); default: return Promise.reject(new Error(`未匹配请求: ${url}`)); } });
- 如果你配置了axios实例的
baseURL,实际请求的url会拼接baseURL,和你case里的路径不匹配,你可以改成模糊匹配避免这个问题:
mockAxios.get.mockImplementation((url) => { if (url.includes('/companies/123/activity') && !url.includes('users')) { return Promise.resolve({ data: [] }); } else if (url.includes('/activity/events')) { return Promise.resolve({ data: [] }); } else if (url.includes('/companies/123/activity/users')) { return Promise.resolve({ data: [] }); } return Promise.reject(new Error(`未匹配请求: ${url}`)); });
第三步:调试查看实际调用参数
如果还是无法拿到参数,可以打印mock的调用记录确认实际传参:
// 在所有请求执行完成后打印get方法的调用历史 console.log(mockAxios.get.mock.calls); // 若用的是配置对象写法则打印axios本身的调用历史 console.log(mockAxios.mock.calls);
完整测试示例
// 测试文件顶部 jest.mock('axios', () => require('jest-mock-axios')); import mockAxios from "jest-mock-axios"; import { render, waitFor } from '@testing-library/react'; import YourComponent from './YourComponent'; test('测试多接口请求返回', async () => { mockAxios.get.mockImplementation((url) => { if (url.includes('/companies/123/activity') && !url.includes('users')) { return Promise.resolve({ data: [] }); } else if (url.includes('/activity/events')) { return Promise.resolve({ data: [] }); } else if (url.includes('/companies/123/activity/users')) { return Promise.resolve({ data: [] }); } return Promise.reject(new Error(`未匹配请求: ${url}`)); }); render(<YourComponent />); await waitFor(() => { expect(mockAxios.get).toHaveBeenCalledTimes(3); }); }); afterEach(() => { // 每次测试后重置mock,避免用例间互相干扰 mockAxios.reset(); });
内容的提问来源于stack exchange,提问作者Nikita Kumari
相关产品推荐
相关产品推荐

