Angular测试中localStorage.removeItem报错的解决求助
解决Angular测试中模拟localStorage出现的AfterAll TypeError问题
嘿,我看到你在Angular测试里模拟localStorage时遇到了这个头疼的AfterAll错误,我之前做Angular测试时也踩过类似的坑,来帮你捋捋问题出在哪以及怎么解决~
问题分析
你现在遇到的AfterAll Uncaught TypeError: localStorage.removeItem is not a function错误,主要有两个核心原因:
- mock方法不完整:你注释掉了
spyOn(localStorage, 'removeItem')这行代码,但测试结束后(AfterAll阶段),你的组件销毁逻辑、Angular的清理流程或者测试框架本身可能调用了localStorage.removeItem,此时因为没有对这个方法做mock,导致调用了被破坏的原生方法(或者测试环境中原生localStorage的方法不可用),从而抛出错误。 - mock对象中clear方法的this指向错误:你的
mockLocalStorage.clear用了箭头函数,里面的this.store并不会指向mock对象的store变量,而是继承了外层作用域的this,这会导致clear方法无法正确清空存储,还可能引发后续测试的状态污染。
解决方案
方案1:修复现有mock并补全所有spy
先修正clear方法的this问题,然后取消注释removeItem的spy代码:
let store: { [key: string]: string } = {}; // 在这里初始化你的测试数据 const mockLocalStorage = { getItem: (key: string): string => { return key in store ? store[key] : null; }, setItem: (key: string, value: string) => { store[key] = `${value}`; }, removeItem: (key: string) => { delete store[key]; }, clear: () => { store = {}; // 直接引用外层的store,不要用this.store } }; // 补全所有需要用到的localStorage方法的spy spyOn(localStorage, 'getItem').and.callFake(mockLocalStorage.getItem); spyOn(localStorage, 'setItem').and.callFake(mockLocalStorage.setItem); spyOn(localStorage, 'removeItem').and.callFake(mockLocalStorage.removeItem); // 取消注释这行 spyOn(localStorage, 'clear').and.callFake(mockLocalStorage.clear); // 每个测试后清空store,避免测试间状态污染 afterEach(() => { store = {}; });
方案2:直接替换整个window.localStorage(更推荐)
这种方式不需要一个个spy方法,直接替换整个localStorage对象,能避免遗漏方法的问题:
let store: { [key: string]: string } = {}; // 初始化测试数据 beforeEach(() => { const mockLocalStorage = { getItem: (key: string): string => store[key] || null, setItem: (key: string, value: string) => { store[key] = value; }, removeItem: (key: string) => { delete store[key]; }, clear: () => { store = {}; } }; // 直接覆盖window上的localStorage对象 Object.defineProperty(window, 'localStorage', { value: mockLocalStorage, writable: true }); }); afterEach(() => { // 每个测试结束后清空存储,保证测试独立性 store = {}; });
额外建议
- 测试时尽量保证每个测试用例的独立性,通过
afterEach清空store,避免前一个测试的状态影响后一个测试。 - 如果你的项目用的是Jest而不是Jasmine,mock方式会略有不同,但核心思路都是完整模拟localStorage的所有方法,避免调用未被mock的原生方法。
内容的提问来源于stack exchange,提问作者CGSL HCM
相关产品推荐
相关产品推荐

