JavaScript单元测试验证异常输入防护逻辑,需主动触发非法输入并断言正确时机、类型及消息的错误抛出;覆盖空值、类型错误、边界值、格式违规等场景;异步函数用rejects断言。

在 JavaScript 单元测试中验证异常输入的防护逻辑,核心是:**主动触发非法输入,检查函数是否按预期抛出错误(而非静默失败或返回错误结果)**。关键不在于“有没有报错”,而在于“是否在正确时机、以正确类型和消息报错”。
用断言明确检查错误抛出
现代测试框架(如 Jest、Vitest、Jasmine)都提供专门的语法来断言异常:
-
Jest:用
expect(() => fn()).toThrow(),支持细化匹配错误类型或消息,例如:expect(() => divide(10, 0)).toThrow(/division by zero/)或.toThrow(TypeError) -
Vitest:语法几乎一致,
expect(() => fn()).toThrow(...),也支持正则、构造函数、字符串精确匹配 -
原生 assert(Node.js):需用
assert.throws(() => fn(), /expected message/),但可读性稍弱
覆盖典型异常输入场景
防护逻辑常针对这几类输入,测试时应逐个覆盖:
-
空值与未定义:
null、undefined、空字符串''、空数组[](若业务不允许) - 类型错误:传入字符串代替数字、对象代替数组、布尔值代替回调等
- 边界值:负数(如年龄、数量)、超大数(溢出风险)、NaN、Infinity
- 格式违规:非法邮箱、非 ISO 格式日期字符串、不符合 schema 的对象结构
验证错误内容而非仅抛出动作
只检查“是否抛错”不够健壮。应进一步确认错误的 类型、消息、甚至附加属性,避免因拼写错误或泛化 throw 导致防护失效:
立即学习“Java免费学习笔记(深入)”;
- 用
.toThrow(TypeError)区分业务错误(CustomError)与类型错误 - 用
.toThrow('Invalid email format')或正则.toThrow(/email/i)确保提示对用户友好 - 若自定义错误类带 code 属性(如
err.code === 'INVALID_INPUT'),可在expect(() => fn()).toThrow()后接expect(fn).toThrow(); const err = fn(); expect(err.code).toBe('INVALID_INPUT');
注意异步函数的错误捕获
对 async 函数,不能直接用 toThrow —— 因为它返回 Promise,需用 rejects:
- Jest/Vitest:
await expect(asyncFn()).rejects.toThrow('Network failed') - 或更安全地:
await expect(asyncFn()).rejects.toMatchObject({ name: 'ValidationError', details: expect.arrayContaining([...]) }) - 避免
try/catch手动包裹再断言,既冗长又易漏掉 Promise rejection 未处理的警告


















