断言异步异常类型应使用 await expect(...).rejects.toThrow(构造函数),可精确匹配错误类;对结构化错误用 toMatchObject 校验属性;手动 try/catch 适用于深度校验或非 Jest 环境;避免无 await 或仅校验消息的误写。

在 JavaScript 单元测试中,断言异步异常的类型,关键在于正确等待 Promise rejection 并校验错误构造函数(如 Error、TypeError、NetworkError 等),而不是只检查错误消息。
用 await expect(...).rejects.toThrow(构造函数)
这是最直接、推荐的方式。Jest 的 .rejects.toThrow() 支持传入错误类,自动比对 error.constructor === 传入的类:
-
await expect(fetchUser('bad-id')).rejects.toThrow(Error)—— 断言抛出的是Error或其子类 -
await expect(apiCall()).rejects.toThrow(TypeError)—— 要求必须是TypeError实例(不是子类) -
await expect(processData(null)).rejects.toThrow(RangeError)—— 精确匹配自定义或内置错误类型
用 await expect(...).rejects.toMatchObject 校验结构化错误
当错误是自定义类(含额外属性),或需验证多个字段时,比单纯类型更可靠:
await expect(fetchUser('404')).rejects.toMatchObject({ name: 'HttpError', status: 404, code: 'NOT_FOUND' })- 注意:该断言要求错误对象具备对应可枚举属性,且值严格相等(浅比较)
- 若属性为 Symbol 或 getter,需改用
try/catch+ 手动expect(error.name)验证
手动 try/catch + 构造函数判断(兼容性最强)
适用于非 Jest 环境,或需深度校验(如原型链、私有字段):
立即学习“Java免费学习笔记(深入)”;
let error; try { await fetchUser('invalid'); } catch (e) { error = e; } expect(error).toBeInstanceOf(NotFoundError);-
expect(error.constructor).toBe(ValidationError);—— 比toBeInstanceOf更严格(排除子类) - 务必确保
error被赋值,且有对应expect,否则无异常时测试会静默通过
避免常见误写
以下写法无法正确断言异常类型,容易导致测试失效:
-
expect(async () => await fn()).toThrow(TimeoutError)—— 错误:这是同步包装,实际返回 Promise,不触发 rejection 捕获 -
expect(fn()).rejects.toThrow(…)—— 错误:缺少await,断言的是 pending Promise,结果不可靠 -
await expect(fn()).rejects.toThrow('Timeout')—— 只校验消息,不校验类型;若将来改错提示但类型不变,此断言仍通过


















