JS转TS后Jest的expect.any()无法匹配自定义AppError类
解决Jest测试中AppError匹配失败问题
问题根源
TypeScript编译后,自定义Error子类的原型链可能未正确设置,导致Jest的expect.any(AppError)无法识别实例类型,误判为普通Error。
解决方案
1. 修复AppError的原型链
在AppError的构造函数中手动设置原型,确保继承关系正确:
class AppError extends Error { public statusCode: number; // 原代码将statusCode定义为string错误,传入的是数字401,建议修正为number类型 public status: string; public isOperational: boolean; constructor(message: string, statusCode: number) { super(message); this.statusCode = statusCode; this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error'; this.isOperational = true; // 修复原型链,确保instanceOf判断生效 Object.setPrototypeOf(this, AppError.prototype); } } export default AppError;
2. 调整测试断言方式
如果原型链修复后仍有问题,可以换用更可靠的断言逻辑:
- 方式一:直接检查实例类型
await authController.login(req, res, next); expect(next).toHaveBeenCalled(); const errorArg = next.mock.calls[0][0]; expect(errorArg).toBeInstanceOf(AppError);
- 方式二:通过自定义属性判断(利用AppError独有的
isOperational属性)
await authController.login(req, res, next); expect(next).toHaveBeenCalledWith( expect.objectContaining({ isOperational: true, statusCode: 401, message: 'Incorrect email or password, or user no longer active' }) );
3. 确保测试文件正确导入AppError
测试文件中要直接导入AppError类,避免使用类型导入:
import AppError from '../utils/appError'; // 正确导入方式 // 禁止使用:import type { AppError } from '../utils/appError';
内容的提问来源于stack exchange,提问作者nicolasdaudin
相关产品推荐
相关产品推荐

