JS数组函数单元测试需紧扣行为契约,覆盖典型、边界、异常场景,验证输入输出确定性、副作用及错误路径,避免复刻实现逻辑,确保测试用例意图明确、可读、可独立运行。

为 JS 数组处理函数写单元测试,核心是覆盖「输入 → 处理 → 输出」的确定性逻辑,重点验证边界、异常和典型场景。不用追求 100% 覆盖,但要让每个测试用例有明确意图、可读、可独立运行。
明确被测函数的行为契约
测试前先厘清函数该做什么:它是否修改原数组(如 push)?是否返回新数组(如 map)?对空数组、null、非数组输入如何响应?比如一个去重函数:
function unique(arr) {
if (!Array.isArray(arr)) throw new TypeError('Expected array');
return [...new Set(arr)];
}
它的契约就很清晰:只接受数组,不改原数组,返回新数组,元素顺序保留。
覆盖典型输入场景(用 Jest 示例)
每个测试用例聚焦一个关注点,命名体现意图:
- 正常情况:含重复项的数字/字符串数组 → 验证去重且顺序不变
- 边界情况:空数组 → 应返回空数组;单元素数组 → 应返回相同数组
-
特殊值:含
undefined、null、NaN的数组 → 注意NaN !== NaN,但Set能正确去重NaN
显式验证副作用与错误路径
如果函数会修改原数组(如 sort() 原地排序),测试中必须保存原始快照再比对:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
const original = [3, 1, 2]; const result = mySort(original); expect(original).toEqual([1, 2, 3]); // 原数组被改 expect(result).toBe(original); // 返回的是原引用
对非法输入,用 expect(() => fn()).toThrow(...) 明确断言错误类型和消息,不只写 toThrow()。
避免“测试即实现”的陷阱
别把测试写成函数内部逻辑的复刻。例如不要这样写:
// ❌ 错误:直接复制了 Set 去重逻辑,没验证行为 expect([...new Set(input)]).toEqual(unique(input));
而应基于外部可观测结果断言:
// ✅ 正确:验证输出长度、元素存在性、顺序、不可变性 expect(unique([1,1,2])).toHaveLength(2); expect(unique([1,1,2])).toContain(2); expect(unique([2,1,1])).toEqual([2,1]); // 顺序保留 expect(input).not.toBe(unique(input)); // 返回新数组
工具选 Jest 或 Vitest 都行,关键在用例设计是否紧扣函数契约。写完反问自己:如果函数实现换了(比如从 Set 改成 filter + indexOf),这些测试是否依然通过且有意义?

















