[英]what is the best way to mock window.sessionStorage in jest
Below is a very simple jest unit test and when running it, you will get error like下面是一个非常简单的 jest 单元测试,运行它时,你会得到如下错误
Cannot spyOn on a primitive value;不能监视原始值; undefined given未定义给定
TypeError: Cannot read property 'getItem' of undefined类型错误:无法读取未定义的属性“getItem”
but according to the last two comments of this post , localStorage and sessionStorage were already added to latest JSDOM and jest.但根据这篇文章的最后两条评论,localStorage 和 sessionStorage 已经添加到最新的 JSDOM 和 jest 中。 If using jest-localstorage-mock and add it to my jest setupFiles then you will see weird error like如果使用jest-localstorage-mock并将其添加到我的 jest setupFiles 那么你会看到奇怪的错误,如
TypeError: object[methodName].mockImplementation is not a function TypeError: object[methodName].mockImplementation 不是 function
So my question is what's the best way to mock localStorage/sessionStorage in jest.所以我的问题是开玩笑地模拟 localStorage/sessionStorage 的最佳方法是什么。 Thanks谢谢
describe('window.sessionStorage', () => {
let mockSessionStorage;
beforeEach(() => {
mockSessionStorage = {};
jest.spyOn(window.sessionStorage, "getItem").mockImplementation(key => {
return mockSessionStorage[key];
});
});
describe('getItem-', () => {
beforeEach(() => {
mockSessionStorage = {
foo: 'bar',
}
});
it('gets string item', () => {
const ret = window.sessionStorage.getItem('foo');
expect(ret).toBe('bar');
});
});
});
Below is my jest config下面是我的笑话配置
module.exports = {
verbose: true,
//setupFiles: ["jest-localstorage-mock"],
testURL: "http://localhost/"
};
Here is the solution only use jestjs
and typescript
, nothing more.这里是解决方案仅使用jestjs
和typescript
,仅此而已。
index.ts
: index.ts
:
export function getUserInfo() {
const userInfo = window.sessionStorage.getItem('userInfo');
if (userInfo) {
return JSON.parse(userInfo);
}
return {};
}
index.spec.ts
: index.spec.ts
:
import { getUserInfo } from './';
const localStorageMock = (() => {
let store = {};
return {
getItem(key) {
return store[key] || null;
},
setItem(key, value) {
store[key] = value.toString();
},
removeItem(key) {
delete store[key];
},
clear() {
store = {};
}
};
})();
Object.defineProperty(window, 'sessionStorage', {
value: localStorageMock
});
describe('getUserInfo', () => {
beforeEach(() => {
window.sessionStorage.clear();
jest.restoreAllMocks();
});
it('should get user info from session storage', () => {
const getItemSpy = jest.spyOn(window.sessionStorage, 'getItem');
window.sessionStorage.setItem('userInfo', JSON.stringify({ userId: 1, userEmail: 'example@gmail.com' }));
const actualValue = getUserInfo();
expect(actualValue).toEqual({ userId: 1, userEmail: 'example@gmail.com' });
expect(getItemSpy).toBeCalledWith('userInfo');
});
it('should get empty object if no user info in session storage', () => {
const getItemSpy = jest.spyOn(window.sessionStorage, 'getItem');
const actualValue = getUserInfo();
expect(actualValue).toEqual({});
expect(window.sessionStorage.getItem).toBeCalledWith('userInfo');
expect(getItemSpy).toBeCalledWith('userInfo');
});
});
Unit test result with 100% coverage report:带有 100% 覆盖率报告的单元测试结果:
PASS src/stackoverflow/51566816/index.spec.ts
getUserInfo
✓ should get user info from session storage (6ms)
✓ should get empty object if no user info in session storage (1ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.ts | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 4.548s, estimated 6s
Here is the completed demo: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/51566816这是完整的演示: https : //github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/51566816
You probably do not even need a mock.您可能甚至不需要模拟。 Just use window.sessionStorage
as usual and write your condition based on window.sessionStorage.getItem(...)
result instead of spying window.sessionStorage.setItem
.只需像往常一样使用window.sessionStorage
并根据window.sessionStorage.getItem(...)
结果而不是监视window.sessionStorage.setItem
编写您的条件。 Simply don't forget to call window.sessionStorage.clear()
in beforeEach
as demonstrated.只需不要忘记在beforeEach
调用window.sessionStorage.clear()
, beforeEach
所示。
This works for me along with adding object:这与添加 object 一起对我有用:
defineProperty(window, 'sessionStorage', {
writable: true,
configurable: true,
value: localStorageMock
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.