如何在Jest测试中取消axios手动Mock,使用真实实现?
在单个Jest测试用例中使用真实Axios而非手动Mock的解决方法
方案一:动态切换为真实Axios(针对单个测试用例)
问题根源是jest.mock会被Jest自动提升到模块作用域最顶部,测试用例内部调用jest.mock时,被测模块已经加载了mock版本的axios,因此不生效。可以通过重置模块缓存并重新引入依赖解决:
// 测试文件顶部先引入被测模块(初始会使用mock的axios) import getContent from '../your-module-path'; // 替换为实际文件路径 test('200 response', async () => { // 1. 取消对axios的mock jest.unmock('axios'); // 2. 清除模块缓存,确保重新加载时获取真实axios jest.resetModules(); // 3. 在unmock和reset之后,重新引入真实axios和被测模块 const { default: realAxios } = await import('axios'); const { default: getContent } = await import('../your-module-path'); // 可选:配置真实axios的基础地址、拦截器等 // realAxios.defaults.baseURL = 'https://your-api-domain'; const response = await getContent('SomeID'); expect(response.id).toEqual('SomeID'); });
方案二:改造手动Mock文件,添加开关控制
在__mocks__/axios.js中增加逻辑,允许测试用例切换真实/mock实现,无需频繁重置模块:
let mockAxios = jest.genMockFromModule('axios'); const originalAxios = jest.requireActual('axios'); let useRealAxios = false; // 暴露开关函数,供测试控制是否使用真实axios export const __setUseRealAxios = (value) => { useRealAxios = value; }; // 重写axios核心方法,根据开关返回对应实现 mockAxios.get = async (...args) => { if (useRealAxios) { return originalAxios.get(...args); } // 原mock逻辑,可根据需求返回预设数据 return Promise.resolve({ data: { id: 'MockID' } }); }; // 同理重写post、put等其他需要的方法 mockAxios.post = async (...args) => { if (useRealAxios) { return originalAxios.post(...args); } return Promise.resolve({ data: {} }); }; export default mockAxios;
在测试用例中调用开关即可:
import getContent from '../your-module-path'; import { __setUseRealAxios } from '../__mocks__/axios'; test('200 response', async () => { // 开启真实axios模式 __setUseRealAxios(true); const response = await getContent('SomeID'); expect(response.id).toEqual('SomeID'); // 测试结束后重置开关,避免影响其他测试用例 __setUseRealAxios(false); });
内容的提问来源于stack exchange,提问作者Yason
相关产品推荐
相关产品推荐

