Возвращаемые значения и реализации

В процессе тестирования с использованием Jest, один из важных аспектов — это правильная обработка возвращаемых значений. Тесты должны проверять не только функциональность, но и корректность возвращаемых результатов из функций, а также их соответствие ожидаемым значениям. В этой главе рассматриваются основные принципы работы с возвращаемыми значениями, методы их тестирования, а также различные реализации, которые могут быть использованы для создания тестов.

Тестирование возвращаемых значений

Каждая функция в JavaScript может возвращать различные типы данных: примитивы (строки, числа, булевы значения), объекты, массивы, а также функции. Важно, чтобы тесты проверяли не только корректность значений, но и соответствие возвращаемых типов.

Для проверки возвращаемого значения в Jest используются утверждения (assertions). Одним из самых популярных методов является toBe:

test('проверка числового результата', () => {
  const result = sum(2, 3);
  expect(result).toBe(5); // Проверка, что возвращаемое значение равно 5
});

Метод toBe используется для строгого сравнения значений, и он проверяет как значения, так и типы данных. Это особенно важно, когда ожидаемое значение — примитив.

Когда возвращаемое значение является объектом или массивом, нужно использовать метод toEqual, который проверяет их структуру и содержимое:

test('проверка объекта', () => {
  const result = getUserData();
  expect(result).toEqual({ name: 'John', age: 30 });
});

Метод toEqual рекурсивно сравнивает объекты и массивы по значениям, не проверяя их ссылки в памяти.

Асинхронные возвращаемые значения

Для тестирования асинхронных функций в Jest существуют специализированные методы, такие как async/await и done для старых версий Jest. При тестировании асинхронных операций важно удостовериться, что результат вернется правильно после завершения асинхронной операции.

Пример с использованием async/await:

test('проверка асинхронной функции', async () => {
  const result = await fetchData();
  expect(result).toEqual({ data: 'Some data' });
});

Метод await заставляет Jest дождаться завершения асинхронной операции перед выполнением утверждения.

Моки и шпионы

Моки (mock) и шпионы (spy) позволяют проверить, как взаимодействует код с внешними зависимостями или как часто вызываются функции. Jest предоставляет встроенные методы для создания моков и шпионов, что делает тестирование внешних вызовов простым и удобным.

Пример использования мока:

test('мок функции', () => {
  const fetchData = jest.fn().mockReturnValue({ data: 'Mock data' });

  const result = fetchData();
  expect(result).toEqual({ data: 'Mock data' });
  expect(fetchData).toHaveBeenCalledTimes(1); // Проверка, что функция была вызвана один раз
});

Метод mockReturnValue позволяет задать, какое значение должна возвращать мокированная функция, а toHaveBeenCalledTimes проверяет, сколько раз была вызвана эта функция.

Шпион используется, когда необходимо проверить, как часто или с какими аргументами была вызвана реальная функция:

test('шпион на метод', () => {
  const obj = { greet: () => 'Hello' };
  const spy = jest.spyOn(obj, 'greet');

  obj.greet();

  expect(spy).toHaveBeenCalled(); // Проверка, что метод был вызван
});

Шпион не меняет поведения функции, но позволяет отслеживать её вызовы.

Работа с функциями высшего порядка

Функции высшего порядка — это функции, которые принимают другие функции как аргументы или возвращают их. В тестах важно проверить, как такие функции возвращают или используют переданные им функции.

Пример функции высшего порядка, которая возвращает другую функцию:

const multiplyBy = (factor) => (number) => number * factor;

test('проверка функции высшего порядка', () => {
  const multiplyByTwo = multiplyBy(2);
  expect(multiplyByTwo(5)).toBe(10);
});

В данном примере multiplyBy возвращает функцию, которая умножает переданное число на заданный множитель. Тест проверяет, что возвращаемая функция работает правильно.

Генерация значений и возвращаемые функции

Существуют ситуации, когда тестируемая функция генерирует случайные значения или возвращает функцию для последующего вызова. В таких случаях тесты должны учитывать динамическую природу возвращаемых значений.

Пример функции, которая возвращает случайное значение:

const getRandomNumber = () => Math.floor(Math.random() * 100);

test('проверка случайного числа', () => {
  const result = getRandomNumber();
  expect(result).toBeGreaterThanOrEqual(0);
  expect(result).toBeLessThan(100);
});

Этот тест проверяет, что случайное число лежит в пределах от 0 до 99, что важно для тестирования таких функций.

Тестирование возвращаемых значений с ошибками

В некоторых случаях функции могут выбрасывать ошибки или возвращать промисы с ошибками. Важно правильно проверять, что ошибки обрабатываются должным образом.

Для проверки выбрасываемых ошибок используется метод toThrow:

test('проверка выброса ошибки', () => {
  const throwError = () => {
    throw new Error('Ошибка');
  };
  expect(throwError).toThrow('Ошибка');
});

Этот тест проверяет, что функция выбрасывает ожидаемую ошибку.

Для асинхронных функций с ошибками используется rejects:

test('проверка асинхронной ошибки', async () => {
  await expect(fetchData()).rejects.toThrow('Ошибка при получении данных');
});

Здесь тест проверяет, что промис, возвращаемый функцией, отклоняется с ожидаемой ошибкой.

Заключение

Тестирование возвращаемых значений в Jest требует внимательности к типам данных, асинхронному поведению, мокающим и шпионским функциям, а также правильной обработке ошибок. Понимание этих принципов позволяет создавать качественные и надежные тесты, которые обеспечивают корректность работы кода в разных ситуациях.