Todor Ivanov
Todor Ivanov

Reputation: 49

How to test localStorage with Jest

Ive mocked localStorage as suggested on another threat but i cant get the tests to work i tried multiple times with no success.

This is the mock

class LocalStorageMock {
  constructor() {
    this.store = {};
  }
  clear() {
    this.store = {};
  }

  getItem(key) {
    return this.store[key] || null;
  }

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

  removeItem(key) {
    delete this.store[key];
  }
}
This is the function that im trying to test.

const setToLS = (target, value) => {
  localStorage.setItem(target, JSON.stringify(value));
};
const saveToLS = (target, item) => {
  let items;
  if (localStorage.getItem(target)) {
    items = utilities.addItem(JSON.parse(localStorage.getItem(target)), item);
  } else {
    items = utilities.addItem([], item);
  }
  setToLS(target, items);
};

This the test that i cant get to work.

describe('utilitiesLS', () => {

  describe('saveToLS', () => {
    it('should save item to LS')', () => {
      const target = 'recipes';
      const item = { name: 'salat', ingredients: 'spinach', id: 1 };
      utilitiesLS.saveToLS(target, item)
      expect(localStorage.store).toMatch( '{"recipes": [{"id": 1, "ingredient": "spinach", "recipeName": "salat"}]}'
      )
    });
  });
});

And this is the error.

 expect(string)[.not].toMatch(expected)

    string value must be a string.
    Received: undefined

      29 |       const item = { recipeName: 'salat', ingredients: 'spinach', id: 1 };
      30 |       utilitiesLS.saveToLS(target, item)
    > 31 |       expect(localStorage.store).toMatch( '{"recipes": [{"id": 1, "ingredient": "spinach", "recipe
Name": "salat"}]}'
         |                                  ^
      32 |       )
      33 |     });
      34 |   });

Upvotes: 1

Views: 5127

Answers (1)

thomasmichaelwallace
thomasmichaelwallace

Reputation: 8482

The problem is your test.

LocalStorageMock.store is an object, but your test expect(localStorage.store).toMatch( '{"reci... is testing it to see if it's a string. This is why your test is not passing, because objects do not match strings.

To fix this you should test:

  expect(localStorage.store).toEqual({"recipes": [{"id": 1, "ingredient": "spinach", "recipeName": "salat"}]})

Noting that localStorage.store is undefined indicates that you are also not getting the constructed instance of your mock that your test is using.

n.b. If you're trying to mock local storage, consider one of the pre-built, tested and documented approaches such as: https://www.npmjs.com/package/jest-localstorage-mock

Upvotes: 2

Related Questions