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