JavaScript单元测试中模拟localStorage需替换window.localStorage对象,用轻量Mock实现setItem等方法并确保状态隔离;Jest可mock模块,Vitest用vi.restoreAllMocks清理;进阶需手动触发StorageEvent。

在 JavaScript 单元测试中模拟 localStorage 行为,核心是**替换全局的 window.localStorage 对象**,使其具备可控制的读写逻辑和状态隔离能力。避免真实操作浏览器本地存储,保证测试可重复、无副作用。
手动创建轻量级 Mock 对象
适用于 Jest、Vitest 或其他测试框架,无需额外依赖:
- 在测试文件顶部或
beforeEach中,用一个普通对象模拟localStorage的键值对存储 - 覆盖
setItem、getItem、removeItem、clear四个关键方法 - 注意:必须同时替换
window.localStorage和global.localStorage(Node 环境下)
示例(Jest):
const localStorageMock = {
store: {},
getItem(key) { return this.store[key] || null; },
setItem(key, value) { this.store[key] = String(value); },
removeItem(key) { delete this.store[key]; },
clear() { this.store = {}; }
};
beforeEach(() => {
Object.defineProperty(window, 'localStorage', { value: localStorageMock });
});
使用 Jest 自带的 jest.mock() 配合模块模拟
如果封装了本地存储工具类(如 StorageUtil.js),推荐直接 mock 整个模块:
- 在测试文件中调用
jest.mock('./StorageUtil') - 用
jest.requireActual保留部分真实行为,或完全替换为 mock 实现 - 更利于解耦,避免污染全局
window
示例:
jest.mock('./StorageUtil', () => {
const store = new Map();
return {
setItem: jest.fn((key, value) => store.set(key, value)),
getItem: jest.fn(key => store.get(key)),
removeItem: jest.fn(key => store.delete(key)),
clear: jest.fn(() => store.clear())
};
});
确保测试间状态隔离
多个测试共用同一份 localStorage 模拟数据会导致干扰,务必重置:
- 在
beforeEach中清空 mock 对象内部存储(如localStorageMock.store = {}) - 或在
afterEach中调用localStorage.clear()(前提是已正确 mock) - Vitest 用户可利用
vi.restoreAllMocks()+vi.unmock()组合清理
处理 StorageEvent 监听器验证(进阶)
若业务代码监听 storage 事件,需模拟触发该事件以验证响应逻辑:
- 在 mock 的
setItem中手动 dispatchStorageEvent - 注意:仅在支持
StorageEvent构造函数的环境(现代浏览器、JSDOM)中有效 - 示例:
window.dispatchEvent(new StorageEvent('storage', { key, newValue }))
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











