JavaScript单元测试中,需通过构造非法输入、mock失败响应、使用toThrow()和rejects断言等方式,主动覆盖try-catch及async/await中的错误分支、finally清理逻辑与嵌套异步错误传播路径。

在 JavaScript 单元测试中,try-catch 和 async/await 不是提高覆盖率的“银弹”,但合理使用它们能帮你覆盖更多边界路径和异步失败场景——尤其是那些容易被忽略的错误分支。
覆盖同步异常路径(用 try-catch 显式触发)
很多函数内部可能 throw 错误(如参数校验、JSON.parse 失败),但默认测试用例只走正常流程。要让测试进入 catch 块,需主动构造非法输入。
- 对可能抛错的函数,写一个“故意出错”的测试用例,比如传 null 给要求非空的参数
- 在测试中用
expect(() => fn()).toThrow()断言异常,这会覆盖 try-catch 中的 error 处理逻辑 - 如果业务代码里已有 try-catch(例如封装 fetch 并 fallback),测试时需 mock 失败响应,确保 catch 内部逻辑被执行
覆盖异步拒绝路径(用 async + await + expect().rejects)
async 函数返回 Promise,失败时不会抛同步错误,而是返回 rejected Promise。不处理它,catch 分支就永远不执行。
- 测试异步函数时,用
await expect(fn()).resolves.toBe(...)覆盖成功路径 - 用
await expect(fn()).rejects.toThrow(...)或rejects.toEqual(...)覆盖 reject 分支,强制进入 catch - 避免在测试里写
try { await fn() } catch (e) { ... }—— 这会让测试本身吞掉错误,反而掩盖未覆盖的异常处理逻辑
模拟异常场景比“真实抛错”更可控
真实环境抛错难复现、不稳定;测试中应通过 mock 控制行为,精准命中目标分支。
立即学习“Java免费学习笔记(深入)”;
- 用 Jest 的
jest.mock()或mockRejectedValue(new Error('...'))让依赖模块返回 reject - 对同步方法,可用
jest.fn().mockImplementation(() => { throw new Error(); }) - 确保 mock 行为与原函数签名一致,否则 await 可能报错,导致测试失败而非覆盖目标逻辑
别忽略 finally 和嵌套异步中的错误传播
finally 总会执行,常用于清理;嵌套 await 可能导致错误被外层 catch 捕获——这些路径也需验证。
- 给含 finally 的逻辑单独写测试,断言清理操作(如关闭连接、重置状态)是否发生
- 多层 async 函数调用时,检查错误是否按预期冒泡或被捕获,避免“静默失败”
- 用
await expect(outerFn()).rejects...验证最外层能否正确处理内层 rejection
不复杂但容易忽略。关键不是堆语法,而是让每个错误分支都有对应测试用例驱动执行。


















