JS中Map与Set单元测试需覆盖增删改查、迭代顺序、引用键/唯一性等核心行为:Map验证原始值与对象键的严格匹配及size实时性,Set验证NaN唯一性、对象引用去重及迭代器一致性。

JS 中 Map 与 Set 的单元测试,核心是验证其行为是否符合规范:Map 要测键值对的增删改查、迭代、引用键支持;Set 要测唯一性、增删查、迭代、对象去重等特性。用 Jest(最常用)或 Vitest 编写即可,无需额外适配。
Map 基础操作测试
重点覆盖 set、get、has、delete、size 和 clear 方法,尤其注意原始值和对象作为键的区别:
- 用字符串/数字键时,
get必须严格匹配类型和值(如map.get("1") !== map.get(1)) - 用对象作键时,要验证“同一引用才能取到值”,不同对象即使内容相同也不共享
-
size随操作实时更新,clear()后应为 0
示例(Jest):
test('Map handles primitive and object keys correctly', () => {
const map = new Map();
map.set('a', 1);
map.set({}, 'obj1');
const objKey = {};
map.set(objKey, 'obj2');
expect(map.get('a')).toBe(1);
expect(map.has(1)).toBe(false); // 类型不同
expect(map.get({})).toBeUndefined(); // 新对象,不相等
expect(map.get(objKey)).toBe('obj2');
expect(map.size).toBe(3);
});Map 迭代与遍历测试
验证 keys()、values()、entries() 和 forEach 返回可迭代对象,且顺序与插入顺序一致(ES6 规范保证):
- 用
Array.from()或展开运算符转成数组后断言内容和顺序 -
forEach回调参数顺序为(value, key, map),需校验三者正确性 - 修改 Map 同时遍历——不建议,但可测
forEach内部set是否影响当前迭代(实际不影响)
示例:
test('Map iteration preserves insertion order', () => {
const map = new Map([['x', 10], ['y', 20], ['z', 30]]);
expect(Array.from(map.keys())).toEqual(['x', 'y', 'z']);
expect(Array.from(map.values())).toEqual([10, 20, 30]);
expect(Array.from(map.entries())).toEqual([['x', 10], ['y', 20], ['z', 30]]);
const keys: string[] = [];
map.forEach((value, key) => {
keys.push(key);
});
expect(keys).toEqual(['x', 'y', 'z']);
});Set 唯一性与结构测试
Set 的关键在于“值唯一”,需覆盖原始值、NaN、对象、Symbol 等特殊情况:
-
NaN === NaN为 false,但 Set 中只存一个NaN(规范特例) - 对象按引用去重:两个
{}是不同元素;同一对象多次add仍只算 1 个 -
Set构造函数传入重复数组,自动去重 -
has和delete对象需用同一引用
示例:
test('Set enforces uniqueness correctly', () => {
const set = new Set();
set.add(1).add(1).add('1').add(NaN).add(NaN);
expect(set.size).toBe(3); // 1, '1', NaN
const obj = {};
set.add(obj).add({}).add(obj);
expect(set.size).toBe(4); // 1, '1', NaN, obj({} 是新对象)
expect(set.has(NaN)).toBe(true);
expect(set.has({})).toBe(false); // 不同引用
});Set 与 Map 的边界场景测试
容易出错的地方,值得单独覆盖:
-
Map.keys()/Map.values()/Map.entries()返回的是迭代器,不是数组——测试不能直接用.push或.length -
Set.prototype[Symbol.iterator] === Set.prototype.values,两者返回相同迭代器,可测一致性 - 清空后重新添加,确认状态重置干净(避免测试污染)
- 传入 null/undefined 给
new Map(iterable)会报错,而new Set(iterable)同理——可加负向测试
示例(负向):
test('Map constructor throws on null iterable', () => {
expect(() => new Map(null as any)).toThrow();
});
test('Set iterator methods are consistent', () => {
const set = new Set([1, 2]);
expect(set.values()).toBe(set[Symbol.iterator]());
});











