JavaScript测试抛异常函数需用断言捕获而非任其崩溃,推荐expect(() => fn()).toThrow()校验错误类型和消息,异步则用await expect(fn()).rejects.toThrow(),避免直接调用致测试中断。

在 JavaScript 中测试抛出异常的函数,核心是用断言捕获并验证错误类型和消息,而不是让测试直接崩溃。现代测试框架(如 Jest、Vitest、Jasmine)都提供了专门的 API 来安全地测试 throw 行为。
使用 expect(fn).toThrow()(推荐,Jest/Vitest)
这是最简洁、语义最清晰的方式 —— 把被测函数**包裹成不执行的引用**,交给断言处理:
- ✅ 正确写法:
expect(() => riskyFunction()).toThrow() - ❌ 错误写法:
expect(riskyFunction()).toThrow()—— 这会立刻执行并抛错,导致测试中断,断言根本没机会运行
还可以进一步校验错误细节:
-
.toThrow('Invalid input')—— 匹配错误消息字符串 -
.toThrow(/invalid/i)—— 匹配正则表达式 -
.toThrow(TypeError)—— 匹配错误构造函数 -
.toThrow(expect.objectContaining({ name: 'CustomError' }))—— 深度匹配错误对象属性(Vitest/Jest v29+)
手动 try/catch + expect(通用,兼容所有环境)
当使用不支持 .toThrow() 的断言库(如 Chai 配合 Mocha),或需要更精细控制时,可手动捕获:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
let error;
try {
riskyFunction();
} catch (e) {
error = e;
}
expect(error).toBeInstanceOf(Error);
expect(error.message).toContain('required');
注意:必须确保 error 在 catch 外声明,否则断言无法访问;同时要确认函数**确实抛出了错误**,否则 error 为 undefined,需额外断言 expect(error).toBeDefined()。
测试异步函数抛出 Promise.reject
对返回 Promise 的函数(如 async function),不能用 .toThrow(),而要用 .rejects:
await expect(asyncFunction()).rejects.toThrow('Network failed')await expect(asyncFunction()).rejects.toBeInstanceOf(TimeoutError)- ⚠️ 不要写
expect(asyncFunction()).rejects...而不加await,否则断言会立即执行,得不到 Promise 的 rejection 结果
避免常见陷阱
测试异常容易踩坑,关键点有:
- 函数调用必须包裹在箭头函数中(
() => fn()),否则执行时机错误 - 不要在测试顶层直接调用可能抛错的函数,会导致整个测试套件中断
- 多个断言共用一个 try/catch 时,确保每个分支逻辑独立,避免遗漏未抛错路径
- 自定义错误类需确保构造函数可被识别(如继承
Error),否则instanceof可能失效

















