Unit Test - Mocking
There are different type of mock that you can add to your test to improve reliability and reduce flakiness.
Date
If you have module/component that use any assumption about current date (either using Date.now() or new Date()) you need to make sure that it can be run any time at any date. If not, you need to mock Date to always point to specific date.
We recommend mockdate NPM module to achieve this. First thing you need to do is add afterEach to reset your date mock to make sure that your other tests don't get affected by mock state in another test.
import MockDate from 'mockdate';
afterEach(() => {
MockDate.reset();
});
Then, set your mock inside each test cases
import MockDate from 'mockdate';
afterEach(() => {
MockDate.reset();
});
test('test #1', () => {
MockDate.set('2019-09-01');
});
test('test #2', () => {
MockDate.set('2019-01-09');
});
API call
To mock API call, you can use nock so instead of mocking implementation detail about your HTTP client, you mock request-response instead. We already provided utilities to help with mocking API call using mockAPI function. This returns nock.Scope so you're free to add modification later on using nock API.
You don't need to add cleanup because when you import mockAPI it will automatically schedule cleanup for you. It also disable network call by default so you'll know if there's an API that you forgot to mock.
There's an optional configuration that you can pass to mockAPI 2nd argument. Both pattern return nock.Scope.
import { mockAPI } from '@traveloka/core/test';
test('only mock hostname', () => {
const scope = mockAPI('accomContent');
scope.post('/v1/hotel/autocomplete').reply(200, { data: {} });
// render & expect here
});
test('mock API url and provide response', () => {
mockAPI('accomContent', {
method: 'post',
path: '/v1/hotel/autocomplete',
response: {
status: 200,
body: {
data: {},
},
},
});
// render & expect here
});
test('mock API proxy', () => {
mockAPI('accomContent', {
clientSide: true,
method: 'post',
path: '/v1/hotel/autocomplete',
response: {
status: 200,
body: {
data: {},
},
},
});
// render & expect here
});
Module
To mock module you can use built-in mock mechanism from Jest. Note that by mocking module, you essentially mock implementation detail. Make sure you're really know the impact of mocking modules to false positive/negative of your test result.
A good test is the one that still works even when implementation detail of your module change.