В процессе тестирования JavaScript-кода с использованием Jest часто возникает необходимость отслеживать, сколько раз был вызван тот или иной мок-функционал, с какими аргументами и какие значения были возвращены. Эта способность значительно облегчает отладку и помогает проверить, что код взаимодействует с зависимостями правильно.
Jest предоставляет несколько инструментов для отслеживания вызовов моков, включая встроенные методы и возможности для создания кастомных моков. В этой главе будет рассмотрено, как эффективно отслеживать вызовы моков, управлять их состоянием и проверять, что тестируемый код работает должным образом.
Мок-объекты — это функции или объекты, которые замещают реальные
зависимости в тестируемом коде. Они помогают изолировать компоненты и
позволяют контролировать поведение зависимостей, чтобы тестировать
только необходимую логику. В Jest моки могут быть созданы с
использованием таких функций, как jest.fn(),
jest.mock() и других.
const myMock = jest.fn();
jest.fn() создаёт мок-функцию, которая позволяет
отслеживать количество её вызовов, переданные параметры и возвращаемые
значения.
Для того чтобы отслеживать вызовы мок-функций, Jest предоставляет несколько встроенных методов. Эти методы дают возможность контролировать, как часто были вызваны моки, какие аргументы были переданы в каждый вызов, и какое значение вернул мок.
Для того чтобы проверить, сколько раз была вызвана мок-функция,
используется метод mock.calls. Этот метод возвращает массив
всех вызовов, сделанных для данной функции.
Пример:
const myMock = jest.fn();
myMock();
myMock();
console.log(myMock.mock.calls.length); // Выведет: 2
Здесь mock.calls.length указывает на количество вызовов
мок-функции.
Если необходимо проверить, с какими аргументами была вызвана функция,
можно использовать mock.calls. Это массив, в котором каждый
элемент соответствует вызову функции и представляет собой массив
аргументов.
Пример:
const myMock = jest.fn();
myMock(1, 'a');
myMock(2, 'b');
console.log(myMock.mock.calls[0]); // Выведет: [1, 'a']
console.log(myMock.mock.calls[1]); // Выведет: [2, 'b']
Каждый элемент mock.calls — это массив аргументов,
переданных при соответствующем вызове.
Для отслеживания возвращаемых значений используется свойство
mock.results. Оно содержит массив с объектами, каждый из
которых соответствует одному вызову мок-функции. Каждый объект имеет два
ключевых поля:
type — тип результата (например, return,
throw, если функция выбрасывает исключение).value — значение, возвращаемое мок-функцией.Пример:
const myMock = jest.fn()
.mockReturnValueOnce(10)
.mockReturnValueOnce(20);
myMock();
myMock();
console.log(myMock.mock.results[0].value); // Выведет: 10
console.log(myMock.mock.results[1].value); // Выведет: 20
Jest также предоставляет возможность делать проверки на мок-функциях в самом тесте, чтобы убедиться, что код ведет себя должным образом.
Для проверки того, сколько раз была вызвана мок-функция, можно
использовать метод .toHaveBeenCalledTimes().
Пример:
const myMock = jest.fn();
myMock();
myMock();
expect(myMock).toHaveBeenCalledTimes(2);
Если необходимо удостовериться, что мок-функция была вызвана с
конкретными аргументами, используется метод
.toHaveBeenCalledWith().
Пример:
const myMock = jest.fn();
myMock(1, 'a');
myMock(2, 'b');
expect(myMock).toHaveBeenCalledWith(1, 'a');
expect(myMock).toHaveBeenCalledWith(2, 'b');
Можно настроить мок-функции так, чтобы они возвращали различные
значения в зависимости от вызова, с помощью методов
.mockReturnValueOnce() и
.mockResolvedValueOnce().
const myMock = jest.fn()
.mockReturnValueOnce(10)
.mockReturnValueOnce(20);
console.log(myMock()); // Выведет: 10
console.log(myMock()); // Выведет: 20
console.log(myMock()); // Выведет: undefined (по умолчанию)
Каждое использование .mockReturnValueOnce() изменяет
поведение функции только для одного вызова.
Для асинхронных функций Jest также предоставляет возможность
мокировать возвращаемые промисы через метод
.mockResolvedValueOnce().
Пример:
const myAsyncMock = jest.fn()
.mockResolvedValueOnce('Success')
.mockResolvedValueOnce('Failure');
myAsyncMock().then(res => console.log(res)); // Выведет: 'Success'
myAsyncMock().then(res => console.log(res)); // Выведет: 'Failure'
Моки могут иметь поведение по умолчанию, которое применимо к каждому
вызову. Это можно настроить с помощью метода
.mockReturnValue().
Пример:
const myMock = jest.fn().mockReturnValue('default value');
console.log(myMock()); // Выведет: 'default value'
myMock.mockReturnValueOnce('specific value');
console.log(myMock()); // Выведет: 'specific value'
console.log(myMock()); // Выведет: 'default value'
Отслеживание вызовов мок-функций — важная часть тестирования, позволяющая убедиться в том, что код правильно взаимодействует с зависимостями. Jest предоставляет мощные инструменты для этого, включая методы для проверки количества вызовов, аргументов, возвращаемых значений и поведения моков. Это помогает сделать тесты более точными и выявлять ошибки на ранних этапах разработки.