应使用 Object.defineProperty 重定义 window.localStorage 属性,通过闭包维护可重置内存 store,完整实现全部方法并派发 storage 事件,在 setupFilesAfterEnv 中统一注入,每次初始化即重置状态,并模拟 QuotaExceededError 异常。

在自动化测试中安全模拟和清理 localStorage,关键不是“临时替换”,而是构建一个可重置、事件兼容、跨测试隔离的内存代理。直接赋值 window.localStorage = {} 会失效或引发跨测试污染,必须通过属性定义 + 闭包状态管理来实现。
用 Object.defineProperty 全量接管读写行为
localStorage 是 window 上的一个非可写、不可配置的属性(尤其在 JSDOM 环境中),仅靠赋值无法覆盖。正确做法是用 Object.defineProperty 重新定义其 descriptor,注入自维护的内存 store:
- 每次测试前调用
createStorageMock()创建全新空对象,确保无历史残留 - mock 对象需完整实现
setItem、getItem、removeItem、clear、key和length,否则调用未 mock 方法时仍走原生逻辑,可能报错或漏触发断言 -
setItem中手动派发storage事件,使被测代码中监听该事件的逻辑可被验证
在 Jest setupFilesAfterEnv 阶段统一注入
Jest 的 setupFilesAfterEnv 是唯一可靠时机——此时 JSDOM 已初始化完成,window 可用,且每个测试文件执行前都会运行该脚本:
- 在
jest-setup-storage.js中定义 mock 并通过Object.defineProperty替换window.localStorage和window.sessionStorage - 配置
jest.config.js启用:setupFilesAfterEnv: ['./tests/jest-setup-storage.js'] - 避免在单个 test 文件里做 mock,否则无法保证 beforeEach/afterEach 的执行顺序与 mock 生效时机一致
测试后自动清理 + 状态重置机制
模拟不是一劳永逸,必须配合生命周期控制:
立即学习“Java免费学习笔记(深入)”;
- 每个
beforeEach不再重复 mock,而是调用localStorage.clear()或重置内部 store 对象(如store = {}) - 不依赖
afterEach清理——万一测试异常中断,状态可能残留;应把重置逻辑放在 mock 初始化阶段本身 - 若需验证清理效果,可在断言中检查
localStorage.length === 0或localStorage.getItem('xxx')返回null
兼容真实异常行为(如 QuotaExceededError)
为覆盖边界场景,mock 可主动模拟容量超限:
- 在 mock 的
setItem中加入计数器或字节估算逻辑,当写入条目数 > 100 或总长度 > 4MB 时,抛出new DOMException('Quota exceeded', 'QuotaExceededError') - 这样被测的
safeSetItem函数才能真正走到 catch 分支,完成异常处理路径的覆盖 - 注意:抛出的 error 必须是标准
DOMException实例,且name属性严格等于'QuotaExceededError',否则业务代码判断会失败


















