Link Search Menu Expand Document

Local Storage: Testing - how to write jest tests involving local storage

Here are some examples of writing jest tests that involve local storage.

Disclaimer

Keep in mind that all code examples on this page were up-to-date at the time they were posted, but that the code base is ever changing. We have used “github permalinks” to link to the source code as it was at the time these were collated.

Clearing localStorage in beforeEach

You may want to clear localStorage in the beforeEach of your test so that each test starts from empty local storage.

This example is from frontend/src/tests/components/PersonalSchedules/PersonalScheduleSelector.test.js

 beforeEach(() => {
    localStorage.clear();
    // ... other code might go here
  });

Mocking localStorage

You can use this lines of code to create a jest mock for localStorage:

    const getItemSpy = jest.spyOn(Storage.prototype, "getItem");

If you want your mock to always return a specific value, say "1", you can create a mock implementation:

    getItemSpy.mockImplementation(() => "1");

An example can be found in frontend/src/tests/components/PersonalSchedules/PersonalScheduleDropdown.test.js (See: Disclaimer).

If your mock implementation needed to be more sophisticated, you could set up an object with the mapping of what you expect to be in localStorage, and then return null if the key is not found:

    getItemSpy.mockImplementation((key) => {
       const values = {
         "key1" : JSON.stringify("value1"),
         "key2" : JSON.stringify("value1")
       }
       return ( key in values ? values[key] : null );
    });

Expect tests onlocalStorage values

We can use expect clauses on localStorage to check that the values were set correctly:

    expect(localStorage.getItem("controlId")).toBe("schedule2");

Here’s an example that shows this in context:

It comes from: frontend/src/tests/components/PersonalSchedules/PersonalScheduleSelector.test.js

First, we [clear localStorage in the beforeEach] on this line

beforeEach(() => {
    localStorage.clear();
    // other code
  });

Then, in the test, we render the component, click on a certain element, and then expect the localStorage value to have been set correctly:

 test("updates the schedule state and calls setSchedule when a schedule is selected", () => {
    const setSchedule = jest.fn();
    render(
      <PersonalScheduleSelector
        controlId="controlId"
        setSchedule={setSchedule}
      />,
    );
    fireEvent.change(screen.getByLabelText("Schedule"), {
      target: { value: "schedule2" },
    });
    expect(localStorage.getItem("controlId")).toBe("schedule2");
    expect(setSchedule).toHaveBeenCalledWith("schedule2");
  });

Legacy Stryker exceptions

You may encounter code in the code base where a Stryker exception was used to bypass mutation testing for code involving localStorage. This should no longer be done, and code that contains such exceptions should be updated to test using the techniques explained earlier on this page.

Here’s an example (which, we can hope, by the time you read this, may already be fixed):

 // Stryker disable all : not sure how to test/mock local storage
  const localSchedule = localStorage.getItem("CourseForm-psId");
  const [schedule, setSchedule] = useState(localSchedule || "");
  if (schedule) {
    localStorage.setItem("CourseForm-psId", schedule);
  }
  // Stryker restore all