javascript单元测试中校验异常需让测试框架捕获而非中断执行,jest/vitest用tothrow需传函数,异步异常须用rejects断言。

在 JavaScript 单元测试中校验异常是否被正确抛出,核心是**让测试框架捕获并断言错误类型和消息**,而不是让异常直接中断测试。不同测试库的写法略有差异,但逻辑一致:把可能抛错的代码包裹在函数中,交由断言工具检查。
使用 Jest 的 toThrow 断言
Jest 提供了专门用于异常校验的 toThrow 匹配器,它要求传入一个函数(而非直接调用),否则会立即抛错导致测试失败。
- ✅ 正确写法:传入函数,Jest 内部执行并捕获异常
- ❌ 错误写法:直接调用,异常未被捕获就终止测试
- 可精确匹配错误构造函数(如
TypeError)、错误消息字符串或正则表达式 - 支持链式断言,例如:
.toThrowError(TypeError).toHaveProperty('message', '...')
使用 Vitest 的 expect().toThrow()
Vitest 语法与 Jest 高度兼容,同样要求传入函数,且支持更细粒度的错误属性断言:
- 基础用法:
expect(() => fn()).toThrow('Invalid input') - 校验错误实例:
expect(() => fn()).toThrowError(TypeError) - 进一步断言错误对象:
const err = expect(() => fn()).toThrowError(); expect(err.message).toContain('required');
手动 try-catch + expect(通用方案)
当需要更灵活控制(比如验证错误堆栈、多条件判断),或使用不支持 toThrow 的断言库(如 Chai)时,可用传统 try-catch:
- 确保
expect在catch块中执行,且try块外有expect(true).toBe(false)类兜底(防漏捕获) - 示例:
try {
divide(5, 0);
} catch (e) {
error = e;
}
expect(error).toBeInstanceOf(Error);
expect(error.message).toMatch(/zero/);
注意异步异常的处理
若被测函数返回 Promise 并在其中 reject,不能用 toThrow,而应使用 rejects:
await expect(asyncFn()).rejects.toThrow('Network failed');await expect(asyncFn()).rejects.toEqual(new Error('...'));- 对 rejected Promise 使用
toThrow会报错:它只处理同步抛错
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











