使用Node原生node:test测试框架模拟axios请求失败求助
解决Node.js原生node:test框架模拟Axios失败的问题
你推测的原因完全正确:测试文件和MyClass中导入的Axios实例并非同一个。node:test的mock.method只能修改当前测试模块内Axios对象的方法,而MyClass模块从Node.js模块缓存中获取的是独立的Axios实例,导致你的Mock根本没作用到目标实例上。
下面提供两种可行的解决方案:
方案一:用mock.module拦截Axios模块导入
直接拦截整个Axios模块的加载,替换成自定义的Mock对象,这样所有导入Axios的模块都会使用这个Mock实例:
修改test.spec.ts如下:
import { describe, test, mock, beforeEach, assert } from 'node:test'; import assert from 'node:assert/strict'; import { MyClass } from './MyClass.ts'; // 注意:Axios真实响应会包含data属性,这里对齐真实返回结构 const mockAxios = { get: async (url: string) => { if (url.startsWith('https://www.my.url')) { return Promise.resolve({ data: { field: 'value' } }); } return Promise.reject(new Error('无效URL')); } }; describe('axios mock test suite', () => { beforeEach(() => { mock.restoreAll(); // 拦截axios模块,替换为我们的Mock对象 mock.module('axios', () => mockAxios); }); // 异步测试必须加async关键字 test('axios mock test', async () => { const o = new MyClass(); const result = await o.doTheThingThatCallsAxios(); assert.deepStrictEqual(result.data, { field: 'value' }); }); });
方案二:依赖注入(更推荐,解耦代码)
修改MyClass,让它通过构造函数接收Axios实例,而不是直接在模块内导入,从根源上避免模块缓存问题:
调整MyClass.ts:
// 仅导入Axios类型,避免绑定具体实例 import type axios from 'axios'; export class MyClass { private axiosInstance; constructor(axiosInstance: typeof axios) { this.axiosInstance = axiosInstance; } public doTheThingThatCallsAxios() { return this.axiosInstance.get('https://www.my.url'); } }
测试文件test.spec.ts:
import { describe, test, assert } from 'node:test'; import assert from 'node:assert/strict'; import { MyClass } from './MyClass.ts'; const mockAxios = { get: async (url: string) => { if (url.startsWith('https://www.my.url')) { return Promise.resolve({ data: { field: 'value' } }); } return Promise.reject(new Error('无效URL')); } }; describe('axios mock test suite', () => { test('axios mock test', async () => { // 直接传入Mock实例 const o = new MyClass(mockAxios as typeof import('axios')); const result = await o.doTheThingThatCallsAxios(); assert.deepStrictEqual(result.data, { field: 'value' }); }); });
这种方式不需要依赖node:test的Mock API,代码耦合度更低,测试灵活性更高,同时也符合依赖注入的设计原则。
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

