-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mocking localstorage #2098
Comments
Found a the solution
And in the jest config: |
Is there a way to do this that relies on a module directly rather than a local file? I want to use a common configuration for document that has |
Found out that "jest": {
"setupFiles": ["@nteract/mockument"]
}, and it loaded that new lerna package properly. 💯 |
It doesn't work for me. It said window is not defined. any idea please? |
@tarim you're probably having |
@thymikee, Thank you very much. |
It worked! Thanks |
How can I test a localStorage failure to test the catch path? |
Example including // browser mocks
const localStorageMock = (function() {
let store = {}
return {
getItem: function(key) {
return store[key] || null
},
setItem: function(key, value) {
store[key] = value.toString()
},
removeItem: function(key) {
delete store[key]
},
clear: function() {
store = {}
},
}
})()
Object.defineProperty(window, 'localStorage', {
value: localStorageMock,
}) |
My take on this: // localStorage.js
export default new class {
store = {};
setItem = (key, val) => (this.store[key] = val);
getItem = key => this.store[key];
removeItem = key => { delete this.store[key]; };
clear = () => (this.store = {});
}(); Usage: // foo.test.js
import localStorage from './localStorage';
window.localStorage = localStorage;
// .. Plus some tests for it: // localStorage.test.js
import localStorage from './localStorage';
describe('localStorage', () => {
beforeEach(() => localStorage.clear());
it('is initialized properly', () => expect(localStorage.store).toEqual({}));
it("returns undefined if requested item doesn't exist", () => {
const foo = localStorage.getItem('foo');
expect(foo).toBeUndefined();
});
it('sets the value of an item', () => {
localStorage.setItem('foo', 'bar');
expect(localStorage.store).toEqual({ foo: 'bar' });
});
it('gets the value of an item', () => {
localStorage.setItem('foo', 'bar');
const foo = localStorage.getItem('foo');
expect(foo).toBe('bar');
});
it('removes an item', () => {
localStorage.setItem('foo', 'bar');
localStorage.removeItem('foo');
const foo = localStorage.getItem('foo');
expect(foo).toBeUndefined();
});
it('clears all items', () => {
localStorage.setItem('foo', 'qwerty');
localStorage.setItem('bar', 'asdf');
expect(localStorage.store).toEqual({ foo: 'qwerty', bar: 'asdf' });
localStorage.clear();
expect(localStorage.store).toEqual({});
});
}); |
There's also https://www.npmjs.com/package/jest-localstorage-mock |
With ES6: `const localStorageMock = (function () { return { }()); Object.defineProperty(window, 'localStorage', { |
Added in this commit |
Oh, that's awesome! It'll probably be within semver range of Jest 22 and 23, then. |
If you're having trouble re-assigning mock storage between tests, try Object.defineProperty(window, 'localStorage', {
value: localStorageMock,
writable: true
}) |
This works when localStorage is being called in the test file, but how can one mock localStorage when it is being used by a service that the test file is calling/testing? |
@remyba You should be able to define it as a mock and get creative with Jest global properties. Maybe something like this answer could help. |
#2098 (comment) 's return store[key] || null If So getItem: function(key) {
return store[key] != null ? store[key] : null
} |
Drawing inspiration from @tripper54 , my test setup looks like this:
In the final For example:
Very simple setup and works flawlessly. Thanks for the advice, all. ❤ |
It doesn't work for something like Object.keys(localStorage) |
I'm using this hook: const mockWindowProperty = (property, value) => {
const { [property]: originalProperty } = window;
delete window[property];
beforeAll(() => {
Object.defineProperty(window, property, {
configurable: true,
writable: true,
value,
});
});
afterAll(() => {
window[property] = originalProperty;
});
};
describe('localStorage test', () => {
mockWindowProperty('localStorage', {
setItem: jest.fn(),
getItem: jest.fn(),
removeItem: jest.fn(),
});
it('localStorage mock works', () => {
window.localStorage.setItem('abc');
expect(window.localStorage.setItem).toHaveBeenCalledWith('abc');
});
}); |
I made some additions to #2098 (comment) and addressed #2098 (comment)
I added support for class MockLocalStorage {
getItem(key) {
return this[key] || null;
}
setItem(key, value) {
this[key] = value.toString();
}
removeItem(key) {
delete this[key];
}
clear() {
Object.keys(this).forEach(k => this.removeItem(k));
}
get length() {
return Object.keys(this).length;
}
} An edge case that this does not support, is setting the localStorage values with keys that have the same names as the methods in the class itself... ie, |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Getting
localStorage is not defined
. Is it a particular way I should go about mocking browser api?The text was updated successfully, but these errors were encountered: