Jest异步测试中自定义异常显示为[object Object]的解决办法
问题
我正在为Jest测试创建一个用于存储请求失败信息的自定义错误类ApiError,代码如下:
/** * Custom error class for errors that happen when fetching data */ class ApiError extends Error { error: string; code: number | null; /** * Custom error class for errors that happen when fetching data */ constructor (code: number | null, error: string) { super(error); this.error = error; this.code = code; } } export default ApiError;
但发现在异步代码中抛出该错误以拒绝Promise时,Jest会将其格式化为[object Object],示例报错信息如下:
● /auth/register › allows users to register [object Object] 78 | // All 400 and 403 errors have an error message 79 | const errorMessage = (json as { error: string }).error; > 80 | throw new ApiError(res.status, errorMessage); | ^ 81 | } 82 | if (![200, 304].includes(res.status)) { 83 | // Unknown error at apiFetch (tests/api/fetch.ts:80:11) at Object.<anonymous> (tests/auth/register.test.ts:5:27)
这导致难以查看具体错误信息。我尝试添加toString()方法:
toString() { return `ApiError: [${this.code}] ${this.error}`; }
但调试发现该方法并未被调用,请问如何让Jest像处理其他错误类型一样打印出可读的错误格式?
解决方案
自定义Error类在TypeScript中必须正确设置原型链,否则Jest无法将其识别为标准Error类型,导致默认格式化输出[object Object]。同时Jest处理异步错误时,优先读取name和message属性,而非直接调用toString()。按以下方式修改即可解决问题:
修正原型链
在构造函数中添加Object.setPrototypeOf(this, ApiError.prototype);,确保自定义错误继承Error的原型方法——这是TypeScript继承内置Error类的必要操作:constructor(code: number | null, error: string) { super(error); this.error = error; this.code = code; Object.setPrototypeOf(this, ApiError.prototype); }添加错误名称
显式设置name属性为类名,让错误类型更清晰:name: string = 'ApiError';优化错误信息展示
直接在父类构造函数中传入包含状态码的完整信息,让Jest输出的错误信息直接包含关键内容:constructor(code: number | null, error: string) { super(`[${code}] ${error}`); this.error = error; this.code = code; Object.setPrototypeOf(this, ApiError.prototype); this.name = 'ApiError'; }
修改后的完整ApiError类示例:
/** * Custom error class for errors that happen when fetching data */ class ApiError extends Error { error: string; code: number | null; name: string = 'ApiError'; constructor(code: number | null, error: string) { super(`[${code}] ${error}`); this.error = error; this.code = code; Object.setPrototypeOf(this, ApiError.prototype); } toString() { return `${this.name}: ${this.message}`; } } export default ApiError;
修改后,Jest捕获到ApiError时会输出类似如下的可读信息:
● /auth/register › allows users to register ApiError: [400] Username already exists ... 栈跟踪信息
内容的提问来源于stack exchange,提问作者Maddy Guthridge
相关产品推荐
相关产品推荐

