Работа с артефактами

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

Мокирование данных

Мокирование (mocking) — это процесс создания имитаций реальных объектов или функций с целью контроля за их поведением во время тестирования. Jest предоставляет функции для создания моков с использованием jest.fn(), jest.mock(), а также для работы с мокированными функциями через методы .mockReturnValue(), .mockResolvedValue() и другие.

Пример мокирования функции

const myFunction = jest.fn().mockReturnValue(42);

test('мокированная функция возвращает правильное значение', () => {
  expect(myFunction()).toBe(42);
});

В этом примере jest.fn() создаёт мокированную функцию, которая всегда возвращает 42. Такой подход позволяет имитировать работу функций, не выполняя реальных вычислений или сетевых запросов.

Мокирование модулей

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

jest.mock('./myModule', () => ({
  myFunction: jest.fn().mockReturnValue(42),
}));

const { myFunction } = require('./myModule');

test('мокированный модуль возвращает правильное значение', () => {
  expect(myFunction()).toBe(42);
});

В данном примере весь модуль myModule будет замокирован, и при вызове функции myFunction будет возвращаться заранее заданное значение.

Шпионы

Шпионы в Jest позволяют следить за вызовами функций, сохраняя информацию о том, как была использована функция, не изменяя её поведения. Это полезно для тестирования, когда важно проверять, были ли вызваны определённые методы или функции.

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

const myFunction = jest.fn();

const obj = {
  method: myFunction,
};

obj.method('test');

test('шпион следит за вызовами функции', () => {
  expect(myFunction).toHaveBeenCalledWith('test');
});

Здесь jest.fn() используется для создания шпионской функции, которая отслеживает вызовы функции method объекта obj. Метод toHaveBeenCalledWith() позволяет проверять, с каким аргументом был вызван шпион.

Снэпшоты

Снэпшоты в Jest используются для проверки неизменности выходных данных, таких как рендеринг компонентов React или сериализованные данные. Снэпшоты создаются с помощью функции toMatchSnapshot(), которая сохраняет состояние данных в файл и позволяет отслеживать изменения в будущем.

Пример создания снэпшота

test('снимок компонента', () => {
  const component = renderer.create(<MyComponent />);
  expect(component.toJSON()).toMatchSnapshot();
});

В этом примере используется библиотека для рендеринга компонентов React, а метод toMatchSnapshot() сохраняет вывод компонента в снэпшот. В дальнейшем Jest будет сравнивать текущий вывод с сохранённым снэпшотом и уведомлять о любых изменениях.

Снэпшоты позволяют тестировать сложные структуры данных и компоненты UI, гарантируя, что изменения в коде не нарушат ожидаемое поведение.

Работа с асинхронными операциями

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

Пример работы с промисами

test('асинхронная функция возвращает правильное значение', async () => {
  const result = await asyncFunction();
  expect(result).toBe('success');
});

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

Пример с использованием done

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

test('асинхронная функция с колбэком', (done) => {
  asyncFunctionWithCallback((result) => {
    expect(result).toBe('success');
    done();
  });
});

В этом примере вызов done() сообщает Jest, что тест завершён.

Таймеры

Jest предоставляет возможность контролировать таймеры (например, setTimeout и setInterval), что особенно полезно при тестировании асинхронных операций с задержкой. Для этого используются функции jest.useFakeTimers() и jest.advanceTimersByTime().

Пример использования таймеров

jest.useFakeTimers();

test('таймер срабатывает правильно', () => {
  const mockCallback = jest.fn();

  setTimeout(mockCallback, 1000);
  jest.advanceTimersByTime(1000);

  expect(mockCallback).toHaveBeenCalled();
});

Здесь jest.useFakeTimers() подменяет работу настоящих таймеров, а метод jest.advanceTimersByTime() позволяет ускорить время и проверить, что таймер сработал после заданной задержки.

Консольные выводы

Иногда важно тестировать вывод в консоль, например, для проверки логирования ошибок или информационных сообщений. Jest предоставляет методы для работы с консолью, такие как console.log, console.error, console.warn и другие.

Пример проверки консольного вывода

test('проверка вывода в консоль', () => {
  const logSpy = jest.spyOn(console, 'log');

  console.log('Hello, world!');
  
  expect(logSpy).toHaveBeenCalledWith('Hello, world!');
  logSpy.mockRestore();
});

Здесь используется шпион для перехвата вызова console.log, а затем проверяется, был ли вызван метод с правильным аргументом.

Работа с файлами

В некоторых случаях в процессе тестирования может возникнуть необходимость работы с файлами, например, для создания или чтения временных данных. Jest позволяет использовать файловую систему через модули Node.js, такие как fs или сторонние библиотеки для работы с временными файлами.

Пример работы с файлами

const fs = require('fs');
const path = './testFile.txt';

test('создание и удаление файла', () => {
  fs.writeFileSync(path, 'Test data');
  const data = fs.readFileSync(path, 'utf-8');

  expect(data).toBe('Test data');

  fs.unlinkSync(path);
});

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

Заключение

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