How to Mock Local Storage in Jest tests

Last Updated:
Mocking local storage in Jest tests

This post contain affiliate links to Udemy courses, meaning when you click the links and make a purchase, I receive a small commission. I only recommend courses that I believe support the content, and it helps maintain the site.

Are you getting the error ‘localStorage is not defined’? Wanting to test localStorage with Jest? This short piece should point you in the right direction!

Firstly, how to mock localStorage?

How to mock localStorage

To mock localStorage in Jest tests we first need to create a mock method. This covers getItem, setItem, removeItem, getAll, and clear.

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

  return {
    getItem(key) {
      return store[key];
    },

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

    clear() {
      store = {};
    },

    removeItem(key) {
      delete store[key];
    },

    getAll() {
      return store;
    },
  };
})();

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

This can be used directly in the test file for a specific, or globally. You can mock localStorage globally for React in Jest by adding the above to the setupTests.js file and adding global.localStorage under the function.

How to use a mock localStorage in tests?

Lets create an example function to test. This function will take an ID and data and add it to localStorage.

const setLocalStorage = (id, data) => {
  window.localStorage.setItem(id, JSON.stringify(data));
};

Now that we have a function to test and have mocked out localStorage, it can be used in our Jest tests. The below shows how to to check that data has been added to localStorage.

test("data is added into local storage", () => {
    const mockId = "1";
    const mockJson = { data: "json data" };
    setLocalStorage(mockId, mockJson);
    expect(localStorage.getItem(mockId)).toEqual(JSON.stringify(mockJson));
  });

This works for individual tests, but you may start running into issues when you have multiple tests for localStorage. It seems that Jest does not clean out the mocked localStorage after each test, leading to buggy tests. We need jest to clear local storage.

How to clear local storage in Jest tests

Thankfully this is an easy fix. We need to add window.localStorage.clear(); and run it before all jest tests. The below code should show how to clear local storage in jest tests. Try the above on your machine, and remove the beforeEach to see the bug re-appear.

describe("Set local storage item", () => {
  beforeEach(() => {
    window.localStorage.clear();
  });

  test("data is added into local storage", () => {
    const mockId = "111";
    const mockJson = { data: "json data" };
    setLocalStorage(mockId, mockJson);
    expect(localStorage.getItem(mockId)).toEqual(JSON.stringify(mockJson));
  });

  test("data in local storage which is overwritten", () => {
    const mockId = "222";
    const mockOldData = { data: "json data" };
    const mockNewData = { data: " new data" };

    window.localStorage.setItem(mockId, JSON.stringify(mockOldData));
    expect(localStorage.getItem(mockId)).toEqual(JSON.stringify(mockOldData));

    setLocalStorage(mockId, mockNewData);
    window.localStorage.setItem(mockId, JSON.stringify(mockNewData));
  });

  test("only one ID is in localStorage", () => {
    const mockId = "333";
    const mockOldData = { data: "json data" };
    const mockNewData = { data: " new data" };

    window.localStorage.setItem(mockId, JSON.stringify(mockOldData));
    setLocalStorage(mockId, mockNewData);

    const allItems = window.localStorage.getAll();

    expect(Object.keys(allItems).length).toBe(1);
  });
});

Hopefully this article has helped, and if you have any questions you can reach me at: @robertmars

Take a look at the article on testing with Jest and React Testing Library for a basic overview of unit testing.

Related Posts

Get helpful Jest Pieces right to your inbox

Keep up to date with all helpful bits of Jest snippets and articles.