Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock localStorage.setIem and localStorage.removeItem in JEST

when i try to mock the localStorage of a react component in jest as below,

spyOn(window.localStorage,'removeItem');
window.localStorage.removeItem("key1");
window.localStorage.removeItem("key2");
expect(window.localStorage.removeItem).toHaveBeenCalledWith("key1");
expect(window.localStorage.removeItem).toHaveBeenCalledWith("key2");

and used the below code for localStorage mocking

let localStorageMock = (function() {
  var storage = {};

  return {
    setItem: function(key, value) {
      storage[key] = value || '';
    },
    getItem: function(key) {
      return storage[key] || null;
    },
    removeItem: function(key) {
      delete storage[key];
    },
    get length() {
      return Object.keys(storage).length;
    },
    key: function(i) {
      var keys = Object.keys(storage);
      return keys[i] || null;
    }
  };
})();
Object.defineProperty(window, 'localStorage', { value: localStorageMock });
like image 226
Nithila Avatar asked Jun 30 '16 15:06

Nithila


People also ask

How to mock localStorage methods with jest?

To mock localStorage methods with Jest, we call jest.spyOn. jest.spyOn (window.localStorage.__proto__, "setItem"); to call jest.spyOn with window.localStorage.__proto__, which is the local storage prototype. We mock the localStorage.setItem method by calling spyOn with 'setItem' as the 2nd argument.

Is localStorage setitem mock getting called?

However localStorage.setItem mock is never getting called. I have also tried doing window.localStorage.setItem = jest.genMockFunction ( ()=> {console.log (" Mock Called")}); global.localStorage.setItem = jest.fn ( ()=> {console.log (" Mock Called")}); Show activity on this post.

How to create the localstoragemock object?

to create the localStorageMock object by creating an IIFE that returns an object that manipulates the store object. It has getItem to return store [key]. setItem sets store [key] to value converted to a string.

Is localStorage an instance of a class?

In short: localStorage is actually an instance of a Storage class. Sadly, mocking methods on a class instance (i.e. localStorage.getItem) doesn't work with our jest.fn approach. But don't fret!


2 Answers

I've done this for session storage for store testing by adding a setup environment script file with the following in;

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

The package.json file then looks like;

"jest": {
    "setupTestFrameworkScriptFile": "jest/jest-setupTestFrameworkScriptFile.js",
}

I'm not actually convinced you need this in the latest version of jest however I've used this setup since a much earlier version.

One thing when using this approach you need to be aware of is that it can persist data between tests so you'll want to add the following in the beforeEach;

sessionStorage = {};
like image 51
Tim Reynolds Avatar answered Oct 23 '22 05:10

Tim Reynolds


I used this in my project's package.json:

"jest": {
  "setupFiles": ["<rootDir>/app/mock/localStorageMock.js"]
}
like image 36
codejockie Avatar answered Oct 23 '22 05:10

codejockie