You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何遍历window.localStorage并解决测试中无法获取键值对的问题

解决测试中window.localStorage遍历失败(length为undefined)的问题

问题核心是你只mock了window.localStorage的getItem、setItem、removeItem方法,但**length属性和key()方法完全没处理**——这俩是遍历localStorage必须用到的,所以测试里window.localStorage.length返回undefined,循环直接不执行,deletePrefixedItem自然没法工作。

修复方案

在测试的beforeEach中,额外mocklength属性和key()方法,让它们基于你维护的store对象返回正确值:

  • 给window.localStorage添加length的getter,返回store对象的键数量
  • mockkey()方法,根据传入的索引返回store里对应的键

修改后的测试用例(以deletePrefixedItem的测试为例)

describe("deletePrefixedItem", () => {
  let store;
  let getItemSpy;
  let setItemSpy;
  let removeItemSpy;
  let keySpy;

  beforeEach(() => {
    store = {};
    
    getItemSpy = spyOn(window.localStorage, "getItem").and.callFake((key) => {
      return store[key] || null;
    });

    setItemSpy = spyOn(window.localStorage, "setItem").and.callFake(
      (key, value) => { 
        store[key] = value.toString();
      });

    removeItemSpy = spyOn(window.localStorage, "removeItem").and.callFake(
      (key) => {
        delete store[key];
      }
    );

    // 新增:mock length属性
    Object.defineProperty(window.localStorage, 'length', {
      get: () => Object.keys(store).length,
      configurable: true // 允许后续重置
    });

    // 新增:mock key方法
    keySpy = spyOn(window.localStorage, "key").and.callFake((index) => {
      const keys = Object.keys(store);
      return keys[index] || null;
    });
  });

  afterEach(() => {
    store = {};
    // 重置length属性,避免影响其他测试
    delete window.localStorage.length;
  });

  it("should delete a item from local storage if it exists", () => {
    // Set the item
    window.localStorage.setItem("myItem", "test");
    window.localStorage.setItem("myItem1234", "test");
    console.log(store);
    // Prints out { myItem: 'test', myItem1234: 'test' }

    // Call deletePrefixedItem function
    deletePrefixedItem();

    expect(removeItemSpy).toHaveBeenCalledWith("myItem1234");

    const item = window.localStorage.getItem("myItem1234");
    expect(item).toBeNull();
  });
});

说明

  • length通过getter实时返回store的键数量,和真实localStorage的行为一致
  • key()方法基于Object.keys(store)的结果返回对应索引的键,保证遍历能拿到所有已设置的键
  • 加上configurable: true和afterEach里的重置,避免这个mock影响其他测试用例

如果后续deleteItem的测试也需要支持遍历逻辑,同样可以把这两个mock加到对应的测试套件里。

内容的提问来源于stack exchange,提问作者Richlewis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 05:49:53