You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 01:20:35