验证异常类型需精准匹配构造函数而非错误消息,Jest/Vitest用toThrowError校验类名,异步场景用rejects,传统断言库可用try-catch+toBeInstanceOf。

在单元测试中验证异常的具体类型,关键不是只看错误消息是否包含某段文字,而是要准确识别错误的构造函数(即错误类名),比如 Error、SyntaxError、TypeError 或自定义错误类。不同测试框架写法略有差异,但核心逻辑一致:把抛错代码包裹成函数,再用断言工具检查其抛出的错误实例类型。
用 toThrowError 匹配构造函数
Jest 和 Vitest 都支持 toThrowError,它能直接校验错误的类型,比单纯用 toThrow 更精准:
- ✅ 正确:匹配构造函数名,不依赖易变的 message
expect(() => parseJSON('{invalid}')).toThrowError(SyntaxError); - ✅ 支持字符串匹配类名(大小写敏感)
expect(() => divide(10, 0)).toThrowError('RangeError'); - ❌ 避免只写
toThrow('RangeError')—— 这是在匹配 message 字符串,不是类型
获取错误实例后做细粒度断言
当需要同时验证类型和属性(如 message、code 等),可先捕获错误对象再断言:
- 在 Vitest 中:
const err = expect(() => throwCustomError()).toThrowError(MyCustomError);<br>expect(err.message).toBe('Invalid ID');<br>expect(err.code).toBe('INVALID_ID'); - 在 Jest 中类似,支持链式调用:
expect(() => fn()).toThrowError(MyCustomError)<br> .toHaveProperty('message', 'required');
手动 try-catch + 构造函数判断(通用方案)
若使用 Chai、Node.js 内置 assert 等不支持 toThrowError 的断言库,或需额外检查堆栈、自定义字段,可用传统方式:
立即学习“Java免费学习笔记(深入)”;
- 确保 try 块内执行,catch 中做判断:
let error;<br>try { unsafeOperation(); } catch (e) { error = e; }<br>expect(error).toBeInstanceOf(TypeError);<br>expect(error.name).toBe('TypeError'); - 注意兜底:若没抛错,error 会是 undefined,需加
expect(error).toBeDefined()防漏断言
异步 Promise 拒绝时的类型校验
对返回 Promise 并调用 reject 或 throw 的函数,不能用 toThrowError,而要用 rejects:
await expect(fetchData('/bad')).rejects.toThrowError(TypeError);await expect(apiCall()).rejects.toBeInstanceOf(ValidationError);- 错误写法:
expect(() => apiCall()).toThrowError(...)—— 这会立即失败,因返回的是 Promise 而非同步抛错


















