Перейти до основного змісту
Версія: 29.1

Підміна модулів

Jest дозволяє підміняти цілі модулі у ваших тестах, що може бути корисним для тестування, якщо ваш код правильно викликає функції з цього модуля. Проте іноді ви можете використовувати частини підміненого модуля в своєму файлі тесту, в цьому випадку ви хочете отримати доступ до оригінальної реалізації, а не до підміненої версії.

Розглянемо написання тестового сценарію для цієї функції createUser:

createUser.js
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, а не підмінену версію. Це означає, що тест тепер пройде правильно.