测试 WeakMap 应避免 Mock,而通过创建独立实例隔离状态:①类中每次 new 创建新 WeakMap;②工具函数接受 WeakMap 参数便于传入干净实例;③专注验证封装接口行为而非 WeakMap 内部;④利用其无 clear 方法和弱引用特性,靠重建而非清理实现测试隔离。

WeakMap 本身无法直接 Mock 或被单元测试“隔离”,因为它不支持遍历、不暴露键列表、且键必须是对象(弱引用)。所以测试 WeakMap 的关键不是 Mock 它,而是控制它的使用方式,确保测试中数据互不影响。
用独立实例隔离测试用例
每个测试用例创建自己的 WeakMap 实例,避免共享状态。这是最简单也最推荐的做法。
- 不要在模块顶层声明 WeakMap(会跨测试污染)
- 把 WeakMap 封装在类或函数作用域内,每次 new 或调用都新建实例
- 例如:
class Cache {
constructor() {
this.store = new WeakMap(); // ✅ 每个实例独享
}
set(obj, value) { this.store.set(obj, value); }
get(obj) { return this.store.get(obj); }
}
// 测试中:
test('should store and retrieve value', () => {
const cache = new Cache(); // 新实例 → 新 WeakMap
const key = {};
cache.set(key, 'data');
expect(cache.get(key)).toBe('data');
});
避免全局 WeakMap,改用依赖注入
如果逻辑强依赖 WeakMap(比如工具函数),把它作为参数传入,而非硬编码创建。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 让函数接受 WeakMap 实例,测试时传入干净的 mock 实例
- 不关心 WeakMap 内部实现,只验证行为是否符合预期
- 示例:
function trackUsage(map, obj) {
const count = map.get(obj) || 0;
map.set(obj, count + 1);
}
// 测试:
test('tracks usage count', () => {
const mockMap = new WeakMap();
const obj = {};
trackUsage(mockMap, obj);
trackUsage(mockMap, obj);
expect(mockMap.get(obj)).toBe(2);
});
不 Mock WeakMap 本身,但可 Mock 使用它的对象
WeakMap 常用于私有状态存储(如封装属性)。此时重点不是测 WeakMap,而是测封装后的接口行为。
立即学习“Java免费学习笔记(深入)”;
- 测试 public 方法是否正确读写内部状态
- 用 toHaveBeenCalled / toHaveBeenCalledWith 验证方法调用(若 WeakMap 操作被封装在 spy 中)
- 不需要断言 WeakMap 内容,只需断言业务结果
注意:WeakMap 无法清空,所以“重置”靠重建
WeakMap 没有 clear() 方法,也无法枚举键。因此测试后不能“清理”,只能确保每次测试用新实例。
- Jest 中可在 beforeEach 里重新初始化 WeakMap 所在对象
- 避免在 afterEach 中尝试“清空”WeakMap(做不到,也不该做)
- 弱引用特性意味着:一旦键对象不可达,条目自动消失——这正是它适合缓存/元数据的原因,也是测试中不必手动清理的依据

















