JavaScript类型转换单元测试应聚焦语言规范与实际场景,按上下文分类验证==、Boolean()、Number()、String()等行为,覆盖null/undefined/NaN/Symbol/BigInt等边界值,并用数据驱动断言确保可读可维护。

JavaScript 中全面验证类型转换的单元测试,关键不是堆砌用例,而是围绕 语言规范行为 和 实际使用场景中的隐式/显式转换边界 设计用例。重点覆盖 ==、===、Boolean()、Number()、String()、parseInt()、parseFloat()、解构、条件判断、JSON 序列化等上下文下的表现,尤其关注 null、undefined、空字符串、特殊数字(NaN、Infinity)、对象、Symbol、BigInt 等易出错值。
聚焦核心转换规则,按上下文分类验证
不要泛泛测试“所有输入”,而是按 JavaScript 强制转换发生的典型上下文分组设计断言:
-
宽松相等(==):必须覆盖
null == undefined(true)、0 == false(true)、'' == false(true)、'0' == false(true)、[] == false(true)、[0] == false(true)、[null] == 0(true)、{} == true(false,但{}在布尔上下文中为 true)等经典陷阱 -
布尔转换(if / while / Boolean()):验证
falsy值(false、0、-0、0n、''、null、undefined、NaN)全为false;注意new Boolean(false)是 truthy 对象,document.all(非标准但存在)在某些环境为 falsy -
数字转换(+、Number()、parseInt):区分
Number('')→0,Number(' ')→0,Number(' 0x10 ')→16(ES5+),而parseInt('')→NaN;Number(null)→0,Number(undefined)→NaN;parseInt(undefined)→NaN,parseInt(null)→NaN(因先转字符串"null") -
字符串转换(+ ''、String()、模板字面量):
String(null)→"null",String(undefined)→"undefined",String(NaN)→"NaN",String({})→"[object Object]",String([1,2])→"1,2",String(Symbol('a'))抛TypeError(需 try/catch 验证)
用真实运行时行为驱动用例,不依赖主观“极端”定义
所谓“极端”,应来自规范或常见 bug 源头,例如:
- 验证
0 === -0为 true,但Object.is(0, -0)为 false;1 / 0→Infinity,1 / -0→-Infinity,Infinity === Infinity为 true,但NaN === NaN为 false - 测试对象转换:
const obj = { valueOf() { return 42; } }; obj + 1→43;若无valueOf但有toString,则走后者;两者都无则报错 - 检查 Symbol 和 BigInt:
Symbol() + ''报错,String(Symbol())正常;BigInt(1) + 1报错(禁止混合运算),但BigInt(1) + BigInt(1)正常 - 验证 JSON 场景:
JSON.stringify([undefined, function(){}, Symbol(), NaN, Infinity])→"[null,null,null,null,null]"(前四项被忽略或转 null,后两项转 null)
用 Jest 或 Vitest 编写可读、可维护的断言
避免长列表 if 判断,用数据驱动 + 明确语义命名:
立即学习“Java免费学习笔记(深入)”;
// 示例:测试 Number() 转换
const numberConversionCases = [
['', 0],
[' \t\n ', 0],
['123', 123],
['0x1A', 26], // 十六进制
['0o17', 15], // 八进制(ES6)
['0b11', 3], // 二进制
[null, 0],
[undefined, NaN],
[[], 0],
[[0], 0],
[[1, 2], NaN],
[new Date('2020-01-01'), 1577836800000],
[new Date('invalid'), NaN],
];
test.each(numberConversionCases)(
'Number(%p) → %p',
(input, expected) => {
expect(Number(input)).toBe(expected);
}
);
对抛错场景,用 expect(() => String(Symbol())).toThrow() 显式验证异常;对 Object.is 等需精确比较的,单独写断言避免误用 ===。
补充运行时环境差异检查(可选但实用)
某些转换行为受环境影响:
- 全局
isNaN()会强制转 Number 再判,Number.isNaN()只认真正的 NaN 类型 —— 必须分别测试 - 浏览器中
document.all在条件判断中为 falsy(历史遗留),但Boolean(document.all)为 true;Node 环境无此对象 - 同一代码在不同 V8 版本中对稀疏数组、超大整数字符串的
parseInt行为可能微调(如科学计数法解析)
这类用例可放在 describe('environment-sensitive') 下并加注释说明适用范围,不作为主流程强依赖。


















