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


当前回答

我从github找到了这个解决方案

var localStorageMock = (function() {
  var store = {};

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

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

您可以在setupTests中插入这段代码,它应该可以正常工作。

我在一个使用typesctipt的项目中测试了它。

其他回答

对于Jest, React和TypeScript用户:

我创建了一个mockLocalStorage.ts

export const mockLocalStorage = () => {
  const setItemMock = jest.fn();
  const getItemMock = jest.fn();

  beforeEach(() => {
    Storage.prototype.setItem = setItemMock;
    Storage.prototype.getItem = getItemMock;
  });

  afterEach(() => {
    setItemMock.mockRestore();
    getItemMock.mockRestore();
  });

  return { setItemMock, getItemMock };
};

我的组件:

export const Component = () => {
    const foo = localStorage.getItem('foo')
    localStorage.setItem('bar', 'true')
    return <h1>{foo}</h1>
}

然后在我的测试中,我这样使用它:

import React from 'react';

import { mockLocalStorage } from '../../test-utils';
import { Component } from './Component';

const { getItemMock, setItemMock } = mockLocalStorage();

it('fetches something from localStorage', () => {
    getItemMock.mockReturnValue('bar');
    render(<Component />);
    expect(getItemMock).toHaveBeenCalled();
    expect(getByText(/bar/i)).toBeInTheDocument()
});

it('expects something to be set in localStorage' () => {
    const value = "true"
    const key = "bar"
    render(<Component />);
    expect(setItemMock).toHaveBeenCalledWith(key, value);
}

在我的例子中,我需要在检查localStorage值之前设置它。

我所做的就是

const data = { .......}

const setLocalStorageValue = (name: string, value: any) => {
  localStorage.setItem(name, JSON.stringify(value))
}



 describe('Check X class', () => {
  setLocalStorageValue('Xname', data)
  const xClass= new XClass()

  console.log(xClass.initiate()) ; // it will work 

  
})

在这个网站的帮助下,我们找到了答案: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”,

要在Typescript中做同样的事情,请执行以下步骤:

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

let localStorageMock = (function() {
  let store = new Map()
  return {

    getItem(key: string):string {
      return store.get(key);
    },

    setItem: function(key: string, value: string) {
      store.set(key, value);
    },

    clear: function() {
      store = new Map();
    },

    removeItem: function(key: string) {
        store.delete(key)
    }
  };
})();
Object.defineProperty(window, 'localStorage', { value: localStorageMock });

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

:“setupTestFrameworkScriptFile PATH_TO_YOUR_FILE”,

或者在您想要模拟本地存储的测试用例中导入该文件。

不需要模拟localStorage—只需使用jsdom环境,这样您的测试就可以在类似浏览器的条件下运行。

在你的joke。config。js中,

module.exports = {
    // ...
    testEnvironment: "jsdom"
}