在Jest测试中,我一直得到“localStorage is not defined”,这是有意义的,但我的选项是什么?碰壁。


当前回答

2022年12月:Nx 14使用Angular 14 Jest。 我们有一个测试设置。Ts文件在每个app和libs文件夹。我们设置本地存储模拟全局。

import 'jest-preset-angular/setup-jest';

Storage.prototype.getItem = jest.fn();
Storage.prototype.setItem = jest.fn();
Storage.prototype.removeItem = jest.fn();

然后localStorage.service.spec.ts文件如下所示:

import { LocalStorageService } from './localstorage.service';

describe('LocalStorageService', () => {
    let localStorageService: LocalStorageService;

    beforeEach(() => {
        localStorageService = new LocalStorageService();
    });

    it('should set "identityKey" in localStorage', async () => {
        localStorageService.saveData('identityKey', '99');
        expect(window.localStorage.setItem).toHaveBeenCalled();
 expect(window.localStorage.setItem).toHaveBeenCalledWith('identityKey', '99');
        expect(window.localStorage.setItem).toHaveBeenCalledTimes(1);
});

it('should get "identityKey" from localStorage', async () => {
    localStorageService.getData('identityKey');
    expect(window.localStorage.getItem).toHaveBeenCalled();
    expect(window.localStorage.getItem).toHaveBeenCalledWith('identityKey');
    expect(window.localStorage.getItem).toHaveBeenCalledTimes(1);
});

it('should remove "identityKey" from localStorage', async () => {
    localStorageService.removeData('identityKey');
    expect(window.localStorage.removeItem).toHaveBeenCalled();
expect(window.localStorage.removeItem).toHaveBeenCalledWith('identityKey');
            expect(window.localStorage.removeItem).toHaveBeenCalledTimes(1);
        });
    });

注:不好意思,这个SatckOverflow窗口很糟糕。

其他回答

Object.defineProperty(window, "localStorage", {
  value: {
    getItem: jest.fn(),
    setItem: jest.fn(),
    removeItem: jest.fn(),
  },
});

or

jest.spyOn(Object.getPrototypeOf(localStorage), "getItem");
jest.spyOn(Object.getPrototypeOf(localStorage), "setItem");

或者你只是像这样使用一个模拟包:

https://www.npmjs.com/package/jest-localstorage-mock

它不仅处理存储功能,还允许您测试是否实际调用了存储。

在这个网站的帮助下,我们找到了答案:https://groups.google.com/forum/#!主题/ jestjs / 9 ephunwvytg

设置一个包含以下内容的文件:

var localStorageMock = (function() {
  var store = {};
  return {
    getItem: function(key) {
      return store[key];
    },
    setItem: function(key, value) {
      store[key] = value.toString();
    },
    clear: function() {
      store = {};
    },
    removeItem: function(key) {
      delete store[key];
    }
  };
})();
Object.defineProperty(window, 'localStorage', { value: localStorageMock });

然后将以下行添加到包中。json在你的Jest配置

:“setupTestFrameworkScriptFile PATH_TO_YOUR_FILE”,

正如Niket Pathak在评论中提到的, 从jest@24 / jsdom@11.12.0及以上开始,localStorage将自动被模拟。

一个更好的替代方法,它处理未定义的值(它不需要toString()),如果值不存在则返回null。用react v15、redux和redux-auth-wrapper进行了测试

class LocalStorageMock {
  constructor() {
    this.store = {}
  }

  clear() {
    this.store = {}
  }

  getItem(key) {
    return this.store[key] || null
  }

  setItem(key, value) {
    this.store[key] = value
  }

  removeItem(key) {
    delete this.store[key]
  }
}

global.localStorage = new LocalStorageMock