在开玩笑中模拟 window.sessionStorage 的最佳方法是什么

2024-01-12

下面是一个非常简单的笑话单元测试,运行它时,你会得到类似的错误

无法监视原始值;未定义给定

类型错误:无法读取未定义的属性“getItem”

但根据最后两条评论这个帖子 https://github.com/facebook/jest/issues/2098,localStorage 和 sessionStorage 已经添加到最新的 JSDOM 和 jest 中。如果使用笑话本地存储模拟 https://www.npmjs.com/package/jest-localstorage-mock并将其添加到我的笑话 setupFiles 然后你会看到奇怪的错误,例如

类型错误:对象[方法名称].mockImplementation 不是函数

所以我的问题是开玩笑地模拟 localStorage/sessionStorage 的最佳方法是什么。谢谢

describe('window.sessionStorage', () => {
    let mockSessionStorage;
    beforeEach(() => {
        mockSessionStorage = {};
        jest.spyOn(window.sessionStorage, "getItem").mockImplementation(key => {
            return mockSessionStorage[key];
        });
    });

    describe('getItem-', () => {
        beforeEach(() => {
            mockSessionStorage = {
                foo: 'bar',
            }
        });

        it('gets string item', () => {
            const ret = window.sessionStorage.getItem('foo');
            expect(ret).toBe('bar');
        });
    });
});

下面是我的笑话配置

module.exports = {
    verbose: true,
    //setupFiles: ["jest-localstorage-mock"],
    testURL: "http://localhost/"
};

这是仅使用的解决方案jestjs and typescript,仅此而已。

index.ts:

export function getUserInfo() {
  const userInfo = window.sessionStorage.getItem('userInfo');
  if (userInfo) {
    return JSON.parse(userInfo);
  }
  return {};
}

index.spec.ts:

import { getUserInfo } from './';

const localStorageMock = (() => {
  let store = {};

  return {
    getItem(key) {
      return store[key] || null;
    },
    setItem(key, value) {
      store[key] = value.toString();
    },
    removeItem(key) {
      delete store[key];
    },
    clear() {
      store = {};
    }
  };
})();

Object.defineProperty(window, 'sessionStorage', {
  value: localStorageMock
});

describe('getUserInfo', () => {
  beforeEach(() => {
    window.sessionStorage.clear();
    jest.restoreAllMocks();
  });
  it('should get user info from session storage', () => {
    const getItemSpy = jest.spyOn(window.sessionStorage, 'getItem');
    window.sessionStorage.setItem('userInfo', JSON.stringify({ userId: 1, userEmail: '[email protected] /cdn-cgi/l/email-protection' }));
    const actualValue = getUserInfo();
    expect(actualValue).toEqual({ userId: 1, userEmail: '[email protected] /cdn-cgi/l/email-protection' });
    expect(getItemSpy).toBeCalledWith('userInfo');
  });

  it('should get empty object if no user info in session storage', () => {
    const getItemSpy = jest.spyOn(window.sessionStorage, 'getItem');
    const actualValue = getUserInfo();
    expect(actualValue).toEqual({});
    expect(window.sessionStorage.getItem).toBeCalledWith('userInfo');
    expect(getItemSpy).toBeCalledWith('userInfo');
  });
});

单元测试结果与 100% 覆盖率报告:

 PASS  src/stackoverflow/51566816/index.spec.ts
  getUserInfo
    ✓ should get user info from session storage (6ms)
    ✓ should get empty object if no user info in session storage (1ms)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 index.ts |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        4.548s, estimated 6s

这是完成的演示:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/51566816 https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/51566816

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在开玩笑中模拟 window.sessionStorage 的最佳方法是什么 的相关文章

随机推荐

  • 我可以在 Android 4.1+ 上强制展开 Android 通知吗? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想知道是否可以强制展开有 2 个按钮的通知 因为我认为如果不展开 用户将找不到它们 Poweramp 似乎实现了这一点 请任何人帮助我
  • Java swing setMaximumSize 不起作用[重复]

    这个问题在这里已经有答案了 可能的重复 setMaximumSize 在 java 中不起作用 https stackoverflow com questions 4061010 setmaximumsize not working in
  • 将逗号分隔的字符串转换为 int PHP? [复制]

    这个问题在这里已经有答案了 有什么方法可以使用 PHP 将 185 345 321 转换为 185345321 吗 是的 有可能 str 185 345 321 newStr str replace str If you want it t
  • 自定义标签助手 - 替换 html 标签

    我创建了一个标签帮助程序 它读取包含元标签的 txt 文件并将内容写入页面 但Process执行后 原来的标签并没有改变 我想用txt文件的内容完全替换原来的标签 标签助手 HtmlTargetElement LC meta public
  • 我可以在数据库设计中避免关系循环吗?

    我尝试为如下所示的情况设计数据库表 我还定义了一个帐户 但这对于我的问题并不重要 有一个操作 费用 列表 每个操作都可以在指定的 POI 中进行 位置可以按链分组 可选 每个操作都可以有一个接收者 特别是连锁店 我当前的设计如下所示 我什至
  • 从 JavaScript 调用 ASP.NET 代码隐藏方法

    有人可以告诉我如何从客户端 JavaScript 调用 ASP NET 代码隐藏方法吗 Thanks 这是一篇关于如何对代码隐藏方法进行 Ajax 调用的非常好的文章 使用jQuery直接调用ASP NET AJAX页面方法 http en
  • C# Visual Studio asp.net 将项目添加到列表属性

    我目前正在开展一个自行车店建模项目 在我的 订单 对象中 我有一个用于订单上自行车商品的 lis 对象 我如何将自行车添加到此列表中 即我想在 创建 视图中显示可用自行车的列表 并将其中一辆或多辆添加到订单中 我的控制器 public Ac
  • 注释 CXF (wsdl2java) 生成的包

    我需要添加包级别注释 XmlJavaTypeAdapters 类型适配器 问题是 当我运行 wsdl2java 时 它会为该包生成 package info java 文件 当我尝试添加自己的 package info java 时 出现错
  • 简化/清理 DOCX Word 文档的 XML

    我有一个 Microsoft Word 文档 docx 我使用Open XML SDK 2 0 生产力工具 http www microsoft com download en details aspx id 5124从中生成 C 代码 我
  • 无法让 Python IDLE 识别 OGR/GDAL 模块

    Folks 刚刚开始使用 OGR 和 Python 来执行各种地理空间任务 我在 OSGEO4w 之外工作 并在我的计算机上安装了带有 Python 绑定的 GDAL 以及 Python v 2 7 8 也就是说 我可以运行 python
  • 从尾部的 qnorm 获取高精度值

    问题 我正在寻找尾部正态分布的高精度值 1e 10 and 1 1e 10 因为我使用的 R 包将任何超出此范围的数字设置为这些值 然后调用qnorm and qt功能 我注意到的是qnorm从尾部来看 R 中的实现并不对称 这对我来说非常
  • 当操作标记内定义命名空间时,如何处理 SOAP 消息的 Castor 解组?

    我正在开发一个基于 Spring WS 的契约优先 Web 服务 我依赖 Castor 封送 并且遇到了以下问题 当 Envelope 标记中定义了 xmlns 命名空间时 请求将被接受 例如
  • TSVN DNS 错误:请求的名称有效,但未找到请求类型的数据

    我已经更新了我的 TortoiseSVN 客户端 现在在尝试更新或提交到不同的存储库时收到错误 请求的名称有效 但没有请求类型的数据 成立 关于如何解决这个问题有什么想法吗 Internet Explorer 可以很好地显示适当的 URL
  • 在高图表上绘制自定义线

    我最近一直在使用 highchart api 在网站上绘制一些数据 并且我需要能够添加自定义垂直 线 来象征正在发生的事情 例如新闻稿 我曾考虑过将列元素作为单独的系列添加到图表中 但这不太理想 如果有人有任何想法那就太好了 thanks
  • Symfony2/JmsDIExtraBundle 使用注释将存储库注入到服务中

    在我的项目中 我使用 JMSDIExtraBundle 注释 我的问题是 我如何告诉我的应用程序存储库应该是服务 这样我就可以使用注释将其注入到另一个服务中 我知道的唯一方法是使用 XML 文件将存储库定义为服务 但这是一个非常缓慢的过程
  • 如何操作facet_grid图的条带文本?

    我想知道如何操纵分面图中条带文本的大小 我的问题 类似于关于剧情标题的问题 https stackoverflow com questions 2631780 r ggplot2 can i set the plot title to wr
  • npm 安装错误 - 未检测到 Xcode 或 CLT 版本?

    在 处找不到 com apple pkg cltools executables 的收据 在 MacOS Catalina 的 VS Code bash 终端中为 Angular 9 项目运行 npm install 时引发上述错误 Pac
  • 列出与 Java 中的模式匹配的目录中的文件[重复]

    这个问题在这里已经有答案了 我正在寻找一种方法来获取与给定目录中的模式 首选正则表达式 匹配的文件列表 我在网上找到了一个使用apache的commons io包的教程 代码如下 Collection getAllFilesThatMatc
  • 在 C/C++ 中高效地在十六进制、二进制和十进制之间转换

    我有 3 种正整数的基本表示形式 十进制 无符号长变量 例如无符号长整型 NumDec 200 十六进制 字符串变量 例如字符串 NumHex C8 二进制 字符串变量 例如字符串 NumBin 11001000 我希望能够以最有效的方式在
  • 在开玩笑中模拟 window.sessionStorage 的最佳方法是什么

    下面是一个非常简单的笑话单元测试 运行它时 你会得到类似的错误 无法监视原始值 未定义给定 类型错误 无法读取未定义的属性 getItem 但根据最后两条评论这个帖子 https github com facebook jest issue