验证async函数抛错需await并用expect(...).rejects.toThrow()断言;不可直接toThrow()或省略await;支持字符串、正则、构造函数及错误结构匹配;非Jest环境可用try/catch校验细节。

验证 async 函数的抛错行为,关键在于正确等待 Promise 的 rejection 状态,并用测试框架提供的断言工具捕获和校验错误,而不是让异常直接中断测试进程。
用 await expect(...).rejects.toThrow() 断言拒绝
这是 Jest/Vitest 中最推荐的方式。async 函数返回的是 Promise,它出错时是被 reject,不是同步 throw,所以不能用 .toThrow() 直接包裹调用。
- ✅ 正确写法:加上
await,并对 Promise 使用.rejects链式断言await expect(fetchUser('bad-id')).rejects.toThrow('Network error'); - 可匹配字符串(子串)、正则或错误构造函数:
await expect(apiCall()).rejects.toThrow(/timeout/i);await expect(apiCall()).rejects.toThrow(TypeError); - 也可校验错误结构:
await expect(apiCall()).rejects.toMatchObject({ code: 'ECONNABORTED' });
不声明 async 时用 return expect(...).rejects
某些老版本 Jest 或需显式返回 Promise 的场景下,可不写 async,而是直接 return 断言本身:
test('rejects on invalid input', () => {<br> return expect(processData(null)).rejects.toThrow('data required');<br>});- Jest 会自动等待该 Promise 完成,效果等同于
await写法
手动 try/catch + expect(通用但需谨慎)
适用于非 Jest 环境,或需要检查错误堆栈、自定义属性等细节:
立即学习“Java免费学习笔记(深入)”;
- 必须在
try中await调用,否则 rejection 不会被捕获 - 确保
catch中有明确的expect,并在try结尾加兜底(如expect(true).toBe(false)),防止无错误时“静默通过” - 示例:
let err;<br>try {<br> await loadData();<br>} catch (e) {<br> err = e;<br>}<br>expect(err).toBeInstanceOf(Error);<br>expect(err.message).toContain('not found');
避开常见错误
- ❌
expect(asyncFn()).toThrow()—— 错误未被 await,断言的是 Promise 实例本身,永远不报错 - ❌
expect(() => asyncFn()).toThrow()—— 包裹的是返回 Promise 的动作,不是执行并等待它失败 - ❌
expect(asyncFn()).rejects.toThrow()...但不加await—— 测试会提前通过,因 Promise 还在 pending - ❌ 在 async 函数里漏掉
await就直接调用 —— rejection 不触发,导致断言失效


















