Node.js Express TypeScript项目中间件测试报错求助
问题排查与修复方案
你的测试代码存在几个关键问题,导致运行报错,以下是具体分析和修复:
1. 测试逻辑与断言完全矛盾
测试描述写的是「当请求session中存在userUUID时,调用next且不抛出Account Not Active错误」,但你的断言却期望next被传入BadRequestError,这完全颠倒了预期结果。
2. 请求对象缺少中间件判断的关键字段
中间件的核心判断条件是req.session?.user?.isEmailVerified,但你构造的测试请求req里,session.user只有userUUID,没有isEmailVerified字段,导致中间件必然进入错误分支,和你的测试预期不符。
3. Mock函数创建错误
res = jest.fn as unknown as Response和next = jest.fn是错误的写法:jest.fn是一个工厂函数,必须通过调用jest.fn()才能生成有效的mock函数,直接赋值jest.fn只是引用了函数本身,无法跟踪调用情况。
4. 不必要的异步调用
你的中间件是同步函数,不需要用await调用,否则会触发Jest对未处理Promise的检测,导致额外错误。
修正后的测试代码
以下是覆盖两种场景的完整测试:
import { Request, Response, NextFunction } from "express"; import { BAD_REQUEST_ERROR_TYPES } from "../constants"; import { BadRequestError } from "../error-handling"; import isAccountActive from "./isAccountActive"; describe("isAccountActive Middleware", () => { describe("处理请求时", () => { test("当用户已邮箱验证(isEmailVerified为true),调用next且不传入错误", () => { // Arrange const req = { session: { user: { userUUID: "some-string", isEmailVerified: true // 补充关键字段 }, }, } as unknown as Request; const res = {} as Response; // 不需要mock完整res,中间件未使用它的方法 const next = jest.fn() as NextFunction; // 正确创建mock函数 // Act isAccountActive(req, res, next); // 同步调用,无需await // Assert expect(next).toBeCalledTimes(1); expect(next).toBeCalledWith(); // 期望无参数调用next }); test("当用户未邮箱验证(isEmailVerified为false或不存在),调用next并传入Account Not Active错误", () => { // Arrange const req = { session: { user: { userUUID: "some-string", isEmailVerified: false // 模拟未验证状态 }, }, } as unknown as Request; const res = {} as Response; const next = jest.fn() as NextFunction; const expectedError = new BadRequestError(BAD_REQUEST_ERROR_TYPES.ACCOUNT_NOT_ACTIVE); // Act isAccountActive(req, res, next); // Assert expect(next).toBeCalledTimes(1); // 由于Error实例是引用类型,需匹配属性而非直接实例 expect(next).toBeCalledWith(expect.objectContaining({ name: expectedError.name, message: expectedError.message, httpStatus: expectedError.httpStatus })); }); }); });
额外说明
- 对于Error实例的断言,不要直接用
new BadRequestError(...)作为匹配值,因为每次创建的实例都是不同的引用,Jest会判定不相等。改用expect.objectContaining匹配关键属性更可靠。 - 如果需要更真实的Request/Response对象,可以使用
node-mocks-http库,它能生成更贴近Express原生对象的mock,减少类型断言的复杂度。
内容的提问来源于stack exchange,提问作者Ange Uwase
相关产品推荐
相关产品推荐

