Home > Enterprise >  How to test if a function set something to localStorage with Jest?
How to test if a function set something to localStorage with Jest?

Time:05-20

I want to test a function that writes something to localStorage using Jest.

The function in question is the following:

const items: = [
  {
    name: 'Item One',
  },
];

export const init = () => {
  if (!localStorage.getItem('items')) {
    localStorage.setItem('items', JSON.stringify(items));
  }
};

My current test looks like this:

import { init } from './MyComponent';

describe('MyComponent', () => {
  test('init method should set items to localStorage', () => {
    init();
    const items = JSON.parse(localStorage.getItem('items'));
    expect(items).toEqual([
      {
        name: 'Item One',
      },
    ]);
  })
});

What am I doing wrong or missing here? I'm importing and calling the function directly but I'm not sure if the test makes sense like this.

Hope someone can guide me..

CodePudding user response:

Assuming that you are using the starter create-react-app project, localStorage is not defined within the test environment by default. The documentation directs users to set it up as below (I had to add as unknown as Storage to localStorageMock as I get compilation errors without it):

const localStorageMock = {
  getItem: jest.fn(),
  setItem: jest.fn(),
  clear: jest.fn()
};
global.localStorage = localStorageMock as unknown as Storage;

This can be added in either your setupTests.ts file, or within your test suite file - either outside of the describe function, or within a suite setup function such as beforeAll.

As you can see, the above explicitly mocks out the localStorage functionality, meaning that the logic that is going to be hit will be mocked out and not function like it would in an integration test. Hence I would refactor your test to the following code, which makes sure that localStorage was called to exhibit correct behaviour:

test('init method should set items to localStorage', () => {
  // act
  init();

  // assert
  expect(localStorageMock.setItem).toHaveBeenCalled();
  // option 1
  expect(localStorageMock.setItem).toHaveBeenCalledWith('items', JSON.stringify([{name: 'Item One'}]))
  // option 2
  const args = localStorageMock.setItem.mock.calls[0];
  expect(args[0]).toEqual('items');
  expect(JSON.parse(args[1])[0].name).toEqual('Item One');
})

Hopefully this helps you!

  • Related