Підміна модулів
Jest дозволяє підміняти цілі модулі у ваших тестах, що може бути корисним для тестування, якщо ваш код правильно викликає функції з цього модуля. Проте іноді ви можете використовувати частини підміненого модуля в своєму файлі тесту, в цьому випадку ви хочете отримати доступ до оригінальної реалізації, а не до підміненої версії.
Розглянемо написання тестового сценарію для цієї функції createUser
:
import fetch from 'node-fetch';
export const createUser = async () => {
const response = await fetch('https://website.com/users', {method: 'POST'});
const userId = await response.text();
return userId;
};
Ваш тест хоче підмінити функцію fetch
, щоб ми могли бути впевнені, що вона викликається, не зробивши мережевий запит. До того ж, вам також буде потрібно підмінити результат роботи функції fetch
на Response
(загорнутий у Promise
), оскільки наша функція вокористовує її, щоб дістати ID створеного користувача. То ж, для початку, ви можете спробувати написати тест наступним чином:
jest.mock('node-fetch');
import fetch, {Response} from 'node-fetch';
import {createUser} from './createUser';
test('createUser calls fetch with the right args and returns the user id', async () => {
fetch.mockReturnValue(Promise.resolve(new Response('4')));
const userId = await createUser();
expect(fetch).toHaveBeenCalledTimes(1);
expect(fetch).toHaveBeenCalledWith('https://website.com/users', {
method: 'POST',
});
expect(userId).toBe('4');
});
Однак, якщо ви запустили цей тест, ви помітите, що функція createUser
викинула помилку: TypeError: response.text is not a function
. Це тому, що клас Response
, який ви імпортували з node-fetch
, було підмінено (через виклик jest.mock
у верхній частині тестового файлу), тому він більше не поводить себе так, як повинен.
Щоб позбутися таких проблем, Jest надає функцію-помічник jest.requireActual
. Щоб тест вище запрацював, внесіть наступні зміни до імпортів у тестовому файлі:
// ДО
jest.mock('node-fetch');
import fetch, {Response} from 'node-fetch';
// ПІСЛЯ
jest.mock('node-fetch');
import fetch from 'node-fetch';
const {Response} = jest.requireActual('node-fetch');
Це дозволяє тестовому файлу імпортувати фактичний об'єкт Response
з node-fetch
, а не підмінену версію. Це означає, що тест тепер пройде правильно.