🧪
JestでsessionStorageの値を使ったテストをする
TypeScriptでいい感じにかけるライブラリとかが見当たらなかったので、自前で書いた覚書。
参考記事
- https://stackoverflow.com/questions/51566816/what-is-the-best-way-to-mock-window-sessionstorage-in-jest
- https://github.com/facebook/jest/issues/2098
setupTests.ts
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,
});
力技的wrapper関数
都度spyOnしてそれをrestoreするコードを書くのめんどいなと思ったので、ラッパーいれます。
export type SessionStorageData = {
[itemName: string]: string;
}
export function withMockSessionStorage<Mock extends SessionStorageData = SessionStorageData>(mockStorageData: Mock, describeFunction: jest.EmptyFunction) {
let spy;
beforeAll(() => {
spy = jest.spyOn(window.sessionStorage, 'getItem')
.mockImplementation((name: string) => {
if (Object.keys(mockStorageData).includes(name)) {
return mockStorageData[name];
}
return null;
});
});
describeFunction();
afterAll(() => {
spy.mockRestore();
});
}
使う
あとはこんな感じで使うだけです。
describeの第二引数と同じ型を指定してあるので、ラッパーの中はdescribeと同じようにかける(はず)です。
describe('with command id in the session storage', () => {
const props = {
siteId: 'xxx-xxx-xxx',
describe: jest.fn()
}
withMockSessionStorage<{
command_id: string
}>({
'command_id': 'session_command_id',
}, () => {
beforeEach(() => {
renderHook(() => useMyCustomHook(props));
});
it('should call describeReuslt by default', () => {
expect(props.describe).toHaveBeenCalledWith('session_command_id');
});
afterEach(() => {
props.describe.mockClear()
})
});
});
Discussion