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

Express router模拟post请求handler未按预期运行问题排查求助

问题根因
  1. 模块加载顺序错误:你在beforeEach中先执行require('../../../bin/www')启动服务时,Express 应用已经完成了原始documents.js路由的加载和挂载,后续测试用例中修改路由对象的post方法,不会对已经启动的服务产生任何影响。
  2. Mongoose 实例 mock 无效:你仅给测试用例中手动创建的user实例挂载了leftDiskSpacemock 方法,但路由内部是通过User.findById从数据库重新查询得到全新的 User 实例,这个新实例没有你挂载的 mock 逻辑,因此 mock 不生效。
解决方案

方案1:mock 整个路由 post 方法(满足你测试 mock 路由是否被调用的需求)

使用 Jest 的jest.mock提前托管路由模块加载,必须放在所有require操作(尤其是启动服务的require('../../../bin/www'))之前:

// 放在测试文件最顶部
jest.mock('../../../routes/documents', () => {
  const express = require('express');
  const mockRouter = express.Router();
  mockRouter.post = jest.fn();
  return mockRouter;
});

const request = require('supertest');
const { Document } = require('../../../models/document');
const { User } = require('../../../models/user');
// 其余原有require内容

后续在测试用例中直接给documentsRouter.post添加自定义实现即可,此时 Express 挂载的就是你 mock 的路由对象,请求可以触发 mock 逻辑。

方案2:仅 mock User 方法(更符合你测试leftDiskSpace是否被调用的原始需求,无需修改路由)

你不需要 mock 整个路由,直接 mock 路由依赖的 User 模型方法即可,有两种实现方式:

方式A:mock User.findById返回值

让findById直接返回你提前配置好 mock 方法的用户实例:

// 在发送请求前添加
const mockLeftDiskSpace = jest.fn().mockRejectedValue(new Error('An error occured...'));
jest.spyOn(User, 'findById').mockResolvedValue({
  ...user._doc, // 保留原有user属性
  leftDiskSpace: mockLeftDiskSpace,
  documents: user.documents,
  save: jest.fn().mockResolvedValue(user) // 可按需mock save方法
});

// 发送请求后断言
expect(mockLeftDiskSpace).toHaveBeenCalled();

方式B:直接 mock User 原型方法

所有 User 实例的自定义方法都挂载在原型上,直接 mock 原型方法可以全局生效:

// 在发送请求前添加
const mockLeftDiskSpace = jest.spyOn(User.prototype, 'leftDiskSpace').mockRejectedValue(new Error('An error occured...'));

// 测试结束后恢复原始方法
afterEach(() => {
  mockLeftDiskSpace.mockRestore();
});

// 发送请求后断言
expect(mockLeftDiskSpace).toHaveBeenCalled();
注意事项
  • 所有 mock 操作必须早于对应模块的加载时机,否则 mock 不会生效
  • 如果做纯集成测试不需要 mock 路由逻辑,仅 mock 业务层依赖即可达到测试目的
  • Supertest 发送的是真实 HTTP 请求,需要保证 Express 挂载的所有依赖都是你 mock 后的版本,否则 mock 逻辑不会被触发

内容的提问来源于stack exchange,提问作者M. Çağlar TUFAN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 03:36:08