はじめに
jestネタです。
何番煎じかわからないtipsもありますが、自分が引っかかったところをまとめたものです。
jest+typescript+reactを想定してます
moment.jsのモック化
moment_mock.test.ts
const mockDate = jest.spyOn(Date, 'now');
beforeEach(() => {
// 当日日付の固定化
mockDate.mockImplementation(() => {
return new Date(2022, 2, 16, 0, 0, 0).getTime();
});
});
外部ファイルのモック化
external_library.test.ts
import * as HogeApi from '../external/HogeApi';
const mockHogeApi = jest.spyOn(HogeApi, 'default');
beforeEach(() => {
mockHogeApi.mockReset();
});
window.locationのモック化
location_mock.test.ts
beforeEach(() => {
window.history.pushState({}, 'Page Title:test', '/route/path');
});
new Audio().play()のモック化
audio_mock.test.ts
const mockPlay = jest.spyOn(window.HTMLMediaElement.prototype, 'play');
beforeEach(() => {
mockPlay.mockReset();
});
非同期のテスト
async.test.ts
it('snapshot', (done) => {
execAsyncFunction();
setTimeout(() => {
try {
expect(mockAsyncApi).toBeCalled();
done();
} catch (e) {
done(e);
}
}, 300);
});
繰り返しテスト
each.test.ts
it.each`
input | expected
${0} | ${'firstActual'}
${1} | ${'secondActual'}
`('each test input=$input',
({ input, expected }) => {
const actual = eachFunction();
expect(actual).toEqual(expected);
}
);
繰り返し+非同期のテスト
each_async.test.ts
it.each`
input | expected
${0} | ${'firstActual'}
${1} | ${'secondActual'}
`('each async test input=$input',
({ input, expected }, done: jest.DoneCallback) => {
eachAsyncFunction();
setTimeout(() => {
try {
expect(mockAsyncApi).toBeCalled();
expect(mockAsyncApi.mock.calls[0][0]).toEqual(expected);
done();
} catch (error) {
done(error);
}
}, 300);
}
);
jqueryのモック化
- プロダクトコード中のjquery関数をモック化したい場合
product.ts
const $ = require('jquery');
const parent = $(e).parents('tr');
jquery_mock.test.ts
jest.mock('jquery', () => {
const m$ = {
// jQuery関数のモック化
parents: jest.fn().mockReturnValue({}),
};
return jest.fn(() => m$);
});
it('test',() => {
// parentsモックの返却値を変更する
const mockAdd = jest.fn();
const $ = require('jquery');
($('').parents as jest.Mock).mockReturnValue([
{ classList: { add: mockAdd } },
]);
callFunction();
expect(mockAdd).toBeCalled();
// parentsモックそのものがcallされたかの検証
expect($().parents).toBeCalled();
});
afterEach(()=>{
// 初期化したいなら
($('').parents as jest.Mock).mockReset();
})
Math.randomのモック化
random_mock.test.ts
beforeEach(() => {
jest.spyOn(global.Math, 'random').mockReturnValue(0.123456789);
});
Modal(react-modal)の描画元を固定化
- react-modalに関するwarningを解消する
console.error
Warning: react-modal: App element is not defined. Please use `Modal.setAppElement(el)` or set `appElement={el}`. This is needed so screen readers don't see main content when modal is opened. It is not recommended, but you can opt-out by setting `ariaHideApp={false}`.
react-modal_mock.test.ts
beforeEach(() => {
Modal.setAppElement(document.createElement('div'));
});
Link(react-router)のモック化
- Linkが含まれるコンポーネントをshallowする時のエラー回避
The above error occurred in the <Link> component:
...
Error: Uncaught [Error: useHref() may be used only in the context of a <Router> component.]
...
link_mock.test.ts
import { MemoryRouter } from 'react-router-dom';
shallow(
<MemoryRouter>
<Component />
</MemoryRouter>
);