mock localstorage/sessionstorage需替换全局对象方法,实现getitem/setitem/removeitem/clear/length,在beforeeach中重置内存对象并用object.defineproperty覆盖,确保测试隔离与断言能力。

在 JavaScript 单元测试中 Mock 本地存储(localStorage 和 sessionStorage),核心是**替换全局对象上的方法或整个对象本身**,使其行为可控、可断言,避免真实写入浏览器环境,也防止测试间数据污染。
手动模拟 localStorage 对象
最常用、最轻量的方式是在每个测试前重置并模拟 localStorage 的基本行为。适用于 Jest、Vitest 等主流测试框架:
- 在
beforeEach中创建一个内存中的键值对对象,然后用它覆盖global.localStorage(或window.localStorage) - 必须实现
getItem、setItem、removeItem、clear和length(只读属性)等接口,否则调用会报错 -
注意:不能直接赋值
localStorage = {...}(因为它是只读的),需用Object.defineProperty或jest.mock替换
const createMockStorage = () => {
let store = {};
return {
getItem: (key) => store[key] || null,
setItem: (key, value) => { store[key] = String(value); },
removeItem: (key) => { delete store[key]; },
clear: () => { store = {}; },
get length() { return Object.keys(store).length; }
};
};
beforeEach(() => {
Object.defineProperty(window, 'localStorage', {
value: createMockStorage(),
writable: true
});
});
使用 Jest 自带的 mock 功能(推荐)
Jest 提供了更简洁可靠的模拟方式,尤其适合隔离性要求高的测试:
- 在测试文件顶部使用
jest.mock模拟整个localStorage模块(但注意:它不能直接 mock 全局对象,需配合Object.defineProperty) - 更稳妥的做法是:在
setupFilesAfterEnv中统一初始化 mock,避免重复代码 - 可用
jest.spyOn监听方法调用,验证是否被正确触发(如expect(localStorage.setItem).toHaveBeenCalledWith('token', 'abc'))
处理 sessionStorage 同理
sessionStorage 的 API 与 localStorage 完全一致,mock 方式完全相同:
- 同样需要实现全部标准方法和
length属性 - 若测试逻辑同时依赖两者,建议分别 mock,避免状态混淆
- 可在同一个
beforeEach中一起定义,也可拆分为独立的辅助函数提升复用性
注意跨测试用例的数据隔离
即使 mock 了 localStorage,若未在每个测试前清空内存对象,上一个测试写入的数据可能影响下一个测试:
- 务必在
beforeEach中重新创建干净的 mock 实例(而不是复用旧对象) - 避免在
beforeAll中初始化,否则多个it共享同一份数据 - 可通过
expect断言初始状态为空(如expect(localStorage.length).toBe(0))来增强健壮性
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











