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

如何在Jest单元测试中Mock Express路由中的db.getUsers函数?

解决Express路由测试中Mock依赖失效的问题

问题根源

你的测试代码存在三个核心问题:

  1. 错误直接调用app.get():Express的app.get()是用来注册路由的方法,无法直接发起HTTP请求,需要用专门的HTTP测试工具。
  2. Mock时机错误:在引入userRoute.js之后才Mockdb模块,此时路由已经加载了原始的db.getUsers引用,后续Mock无法生效。
  3. 缺少必要的模块引入:测试代码中未引入express模块。

解决步骤

1. 安装测试依赖

首先安装supertest,它是专门用于测试Express HTTP接口的工具:

npm install --save-dev supertest

2. 修正测试代码(推荐方案:使用jest.mock)

核心逻辑是先Mockdb模块,再加载路由和Express实例,确保路由使用的是Mock后的db引用:

const express = require("express");
const request = require("supertest");

// 提前Mock整个db模块
jest.mock('./db', () => ({
  getUsers: jest.fn()
}));

const db = require('./db');
const router = require("./userRoute.js");
const app = express();
app.use(express.json()); // 可选:解析JSON请求,适配多数场景
app.use("/", router);

describe("Users Route", () => {
  test("getUsers Happy Path", async () => {
    // 设置Mock的异步返回值
    db.getUsers.mockResolvedValue({
      id: 12345,
      name: "Jason",
      age: "34"
    });

    // 用supertest发起真实的HTTP请求模拟
    const response = await request(app).get("/users/");

    // 断言响应结果
    expect(response.statusCode).toBe(200);
    expect(response.body).toEqual({
      status: 200,
      data: { id: 12345, name: "Jason", age: "34" }
    });
    // 验证Mock函数被正确调用
    expect(db.getUsers).toHaveBeenCalledTimes(1);
  });
});

3. 备选方案:使用jest.spyOn

如果偏好使用spyOn,同样要保证Mock时机在路由加载之前:

const express = require("express");
const request = require("supertest");
const db = require('./db');

// 在引入路由前,先Spy并Mock目标方法
jest.spyOn(db, "getUsers").mockResolvedValue({
  id: 12345,
  name: "Jason",
  age: "34"
});

const router = require("./userRoute.js");
const app = express();
app.use("/", router);

describe("Users Route", () => {
  test("getUsers Happy Path", async () => {
    const response = await request(app).get("/users/");

    expect(response.statusCode).toBe(200);
    expect(response.body.data).toEqual({ id: 12345, name: "Jason", age: "34" });
    expect(db.getUsers).toHaveBeenCalled();
  });
});

关键注意事项

  • 模块缓存机制:Node.js会缓存已加载的模块,因此必须在加载依赖目标模块的文件(这里是userRoute.js)之前完成Mock。
  • 异步Mock处理:因为db.getUsers是被await调用的异步函数,必须使用mockResolvedValue返回Promise,或在mockImplementation中手动返回Promise.resolve(...)。
  • HTTP请求模拟:必须用supertest这类工具模拟请求,Express实例本身不提供发起请求的能力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 05:45:42