It is impossible to mock a localStorage
method
Using the following code:
it( 'setItem mock fn', () => {
const mockFn = jest.fn( localStorage.setItem );
localStorage.setItem = mockFn;
localStorage.setItem( 'foo', 'bar' );
expect( mockFn ).toHaveBeenCalledTimes( 1 );
} );
I have the following error: Expected mock function to have been called one time, but it was called zero times.
No error should be thrown, since setItem
is called during the test.
npx envinfo --preset jest
System:
OS: Linux 4.15 Pop!_OS 18.04 LTS
CPU: x64 Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz
Binaries:
Node: 10.9.0 - /usr/local/bin/node
npm: 6.2.0 - /usr/local/bin/npm
npmPackages:
jest: ^23.5.0 => 23.5.0
I suppose this is related to an error I saw earlier, making me think that localStorage
and sessionStorage
are proxies.
See discussion on #6798
Brilliant! For those with the error, simply use spy: const spy = jest.spyOn(Storage.prototype, 'setItem');
@GerkinDev Problem with this workaround is that you can't distinguish between local and session storage.
The fix @GerkinDev posted works for me. const spy = jest.spyOn(Storage.prototype, 'setItem');
I posted a solution here: https://github.com/facebook/jest/issues/6798#issuecomment-437537691
For those wanting to mock localstorage and not simply spy on it, this worked for me:
Storage.prototype.getItem = jest.fn(() => 'bla');
Here's a utility function for mocking any window property with automatic cleanup:
https://gist.github.com/mayank23/7b994385eb030f1efb7075c4f1f6ac4c
For those wanting to mock localstorage and not simply spy on it, this worked for me:
Storage.prototype.getItem = jest.fn(() => 'bla');
Oh my fucking god, I was doodling around with localStorage mocks for some hours now, your version is ze best:D Thanks a ton
if (localStorage.user) {
const user = JSON.parse(localStorage.getItem("user"));
store.dispatch(currentUser(user));
}
how to write Unit test case for this in React ..??
Most helpful comment
Brilliant! For those with the error, simply use spy:
const spy = jest.spyOn(Storage.prototype, 'setItem');