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

React测试Mock localStorage时触发JSON.parse错误该如何解决?

问题分析与解决方案

核心问题

  • Key大小写不匹配:组件中读取的是"lastplayed"(全小写),但测试代码中设置的是"lastPlayed"(驼峰),导致localStorage.getItem("lastplayed")返回undefined而非预期的null。此时逻辑或||的左侧条件不成立,会执行右侧的getTimeDiff(),进而触发JSON.parse(undefined)的语法错误。
  • Mock的localStorage行为不符合真实环境:真实浏览器的localStorage仅支持存储字符串,调用setItem存入null时会自动转为字符串"null",但当前Mock实现直接存储了null值,和真实行为存在差异。

解决方案

1. 统一Key的大小写

将测试代码中的"lastPlayed"改为和组件一致的"lastplayed":

it("Renders game part of the component when lastPlayed is null", () => {
  localStorage.setItem("lastplayed", null); // 修正为全小写key
  render(<Game />);
  // ... 其余断言代码
});

2. 修正Mock的localStorage行为,匹配真实环境

修改setItem和getItem的Mock实现,确保和真实localStorage的行为一致:

beforeAll(() => {
  global.Storage.prototype.setItem = jest.fn((key, value) => {
    // 模拟真实localStorage:所有值转为字符串存储
    mockStorage[key] = String(value);
  });
  global.Storage.prototype.getItem = jest.fn((key) => {
    // 若key不存在,返回null而非undefined,匹配真实行为
    return mockStorage.hasOwnProperty(key) ? mockStorage[key] : null;
  });
});

3. 优化组件中的条件判断(可选但推荐)

为避免localStorage.getItem返回undefined的情况(比如key拼写错误),调整条件判断逻辑:

return(
  <div>
    {
      // 先判断值是否为空,再执行getTimeDiff
      !localStorage.getItem("lastplayed") || getTimeDiff() >= 24 ? 
      (<SubComponent/>) : 
      (<AnotherComponent/>) 
    }
  </div>
)

更严谨的写法:

const lastPlayed = localStorage.getItem("lastplayed");
return(
  <div>
    {
      (lastPlayed === null || lastPlayed === undefined || getTimeDiff() >= 24) ? 
      (<SubComponent/>) : 
      (<AnotherComponent/>) 
    }
  </div>
)

4. 为getTimeDiff添加容错处理

即使前面的条件都处理完毕,也可以给getTimeDiff加一层容错,避免意外的JSON解析错误:

function getTimeDiff() {
  let currentDay = new Date().toISOString();
  let prevPlayStr = localStorage.getItem("lastplayed");
  
  // 若值无效,直接返回24,满足显示SubComponent的条件
  if (!prevPlayStr) return 24;
  
  let prevPlay = JSON.parse(prevPlayStr);
  let diff = differenceInHours(parseISO(currentDay), parseISO(prevPlay));
  console.log(currentDay + " and " + prevPlay);
  return diff;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 12:57:36