JavaScript单元测试捕获异步reject错误需确保测试框架等待Promise结束并识别拒绝状态:推荐用await expect(...).rejects(测试函数须async)、return expect(...).rejects(兼容旧版)或手动try/catch+await,须避免忽略Promise、语法错误及误用同步异常。

在 JavaScript 单元测试中捕获异步 reject 错误,核心是让测试框架能正确等待 Promise 结束,并识别其拒绝状态。不能靠普通 try/catch 包裹异步调用,也不能只写 expect(...).rejects 而不处理执行时机。
用 await expect(...).rejects(推荐)
这是 Jest 等主流测试工具的标准写法,语义清晰、不易出错:
- 测试函数必须声明为
async -
await必须作用于整个expect(...).rejects链,否则测试会提前通过 - 支持多种断言方式:匹配错误消息、构造器类型或正则
示例:
test('fetchUser 拒绝时抛出网络错误', async () => {
await expect(fetchUser('invalid-id')).rejects.toThrow('Network error');
// 或更精确
await expect(fetchUser('invalid-id')).rejects.toEqual(new Error('Network error'));
await expect(fetchUser('invalid-id')).rejects.toMatch(/network/i);
});
用 return expect(...).rejects(兼容旧版或非 async 场景)
适用于 Jest 版本较老、或测试函数不希望标记为 async 的情况。Jest 会自动等待返回的 Promise:
立即学习“Java免费学习笔记(深入)”;
- 直接
return整个expect(...).rejects表达式 - 不加
await,也不需要async函数声明 - 本质是显式返回一个待测 Promise,由 Jest 生命周期接管
示例:
test('fetchUser 返回被拒 Promise', () => {
return expect(fetchUser('invalid-id')).rejects.toThrow('404 Not Found');
});
手动 try/catch + await(通用但需谨慎)
适合极简环境(如 Node.js 原生 test runner 早期版本),或需要对错误对象做多步检查的场景:
- 必须
await被测 Promise,否则catch捕不到 - 要确保
error变量被赋值,且后续有对应expect - 漏掉任一环节(比如没
await、没expect)会导致“假通过”
示例:
test('fetchUser 抛错时进入 catch', async () => {
let error;
try {
await fetchUser('invalid-id');
} catch (e) {
error = e;
}
expect(error).toBeInstanceOf(Error);
expect(error.message).toContain('timeout');
});
常见陷阱提醒
这些错误会让测试看似通过,实则未真正验证 reject 行为:
-
expect(fetchUser('id')).rejects...没加await或return→ Promise 被忽略,测试立即结束 - 在非
async函数里写await→ 语法错误 - 用
throw new Error()替代Promise.reject()测试工具函数 → 同步异常,不属于 Promise reject 流程 - 传字符串给
Promise.reject('msg')→ 虽可工作,但丢失堆栈,建议统一用new Error()


















