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

Node.js路由Mock函数问题:无法Mock类方法返回结果

解决Node.js路由测试中Mock类字段箭头函数的问题

我来帮你排查下Mock失败的核心问题,然后给出可行的解决方案:

问题根源分析

你现在的Mock失效主要有两个关键原因:

  1. 类A的myFunc是类字段箭头函数,而非原型方法
    你用myFunc = async () => {...}这种类字段语法定义的函数,是直接挂载到每个实例对象上的,并不会出现在A.prototype上。所以测试里修改A.prototype.myFunc完全不会影响new A()创建的实例。
  2. Jest Mock的路径或方式有误
    首先要确保jest.mock('A')的路径和你控制器中引入A的路径一致,比如A的文件是../A.js,就得写成jest.mock('../A'),否则Jest找不到要Mock的模块。

方案一:不修改类A代码,Mock实例方法

我们可以让Jest直接Mock类的构造逻辑,让它返回带有Mock版myFunc的实例:

const request = require("supertest");
const app = require("../C");
// 注意路径要和控制器中引入A的路径一致
const A = require("../A");

// Mock整个A类,指定构造时返回的实例内容
jest.mock("../A", () => {
  return jest.fn().mockImplementation(() => {
    return {
      // 直接Mock实例上的myFunc,用mockResolvedValue处理异步返回
      myFunc: jest.fn().mockResolvedValue("Mocked Success Result")
    };
  });
});

test("Test route /", async () => {
  const res = await request(app).get("/");
  
  expect(res.status).toBe(200);
  expect(res.body).toEqual({ message: "Mocked Success Result" });
  // 验证类被实例化、方法被调用
  expect(A).toHaveBeenCalled();
  expect(A.mock.instances[0].myFunc).toHaveBeenCalled();
});

方案二:修改类A代码(更推荐),改为原型方法

如果可以调整类A的写法,把箭头函数改成普通原型方法,Mock会更符合常规测试逻辑:

修改后的类A代码:

class A {
  async myFunc() {
    await ...
    return result
  }
}

对应的测试文件:

const request = require("supertest");
const app = require("../C");
const A = require("../A");

jest.mock("../A");

test("Test route /", async () => {
  // Mock原型上的myFunc方法
  const mockMyFunc = jest.fn().mockResolvedValue("Mocked Result");
  A.prototype.myFunc = mockMyFunc;

  const res = await request(app).get("/");
  
  expect(res.status).toBe(200);
  expect(res.body).toEqual({ message: "Mocked Result" });
  expect(mockMyFunc).toHaveBeenCalled();
});

额外优化建议

你控制器里的错误处理有个小问题:catch(e => { return [] }),这里如果myFunc抛出错误,你只是返回了空数组,但没有给客户端发送响应,会导致请求挂起、测试超时。建议改成async/await写法并返回错误响应:

router.get("/", async (req, res) => {
  const a = new A();
  try {
    const result = await a.myFunc();
    res.json({ "message": result });
  } catch(e) {
    res.status(500).json({ error: e.message });
  }
});

内容的提问来源于stack exchange,提问作者Iqbal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 12:47:29