Программный API Jest

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

1. Основные методы для запуска тестов

test() — это основной метод для написания тестов в Jest. Он позволяет задать описание теста и функцию, которая будет выполнена.

test('должен корректно суммировать два числа', () => {
  expect(1 + 1).toBe(2);
});

it() является алиасом для test(), и поведение этих методов идентично. Рекомендуется использовать оба метода в зависимости от предпочтений.

it('должен корректно суммировать два числа', () => {
  expect(1 + 1).toBe(2);
});

2. Ожидания (Matchers)

Jest предоставляет мощные механизмы для утверждений, которые называются Matchers. Они используются для проверки значений, которые возвращает тестируемый код.

Пример:

expect(1 + 1).toBe(2);  // Проверка на равенство
expect([1, 2, 3]).toContain(2);  // Проверка на наличие элемента

Основные матчеры:

  • toBe(value) — проверка на строгое равенство.
  • toEqual(value) — проверка на глубокое равенство объектов.
  • toContain(value) — проверка на наличие значения в коллекции.
  • toHaveBeenCalled() — проверка на вызов функции.

3. Работа с асинхронными тестами

Асинхронные тесты в Jest могут быть реализованы с помощью нескольких подходов. Для работы с асинхронными функциями Jest предоставляет следующие методы:

async/await:

test('должен вернуть данные с API', async () => {
  const data = await fetchData();
  expect(data).toBeDefined();
});

done() используется для указания Jest, что тест асинхронный и завершится позже.

test('работа с асинхронной функцией', done => {
  fetchData().then(data => {
    expect(data).toBeDefined();
    done();
  });
});

returnsPromise():

test('работа с промисами', () => {
  return expect(fetchData()).resolves.toBeDefined();
});

4. Мокирование и шпионы (Mocking and Spying)

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

jest.fn() создаёт мок-функцию:

const mockFn = jest.fn();
mockFn();
expect(mockFn).toHaveBeenCalled();

jest.spyOn() позволяет отслеживать вызовы методов объекта, не изменяя его исходного поведения:

const obj = {
  method: () => 'Hello'
};
const spy = jest.spyOn(obj, 'method');
obj.method();
expect(spy).toHaveBeenCalled();

jest.mock() используется для замены импортированных модулей или функций:

jest.mock('module', () => ({
  function: jest.fn(() => 'Mocked')
}));

5. Работа с временными функциями

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

jest.useFakeTimers() — замена стандартных функций таймеров на моки, что позволяет управлять временем в тестах.

jest.useFakeTimers();
test('таймер срабатывает через 2 секунды', () => {
  const mockFn = jest.fn();
  setTimeout(mockFn, 2000);
  jest.advanceTimersByTime(2000);
  expect(mockFn).toHaveBeenCalled();
});

jest.setSystemTime() — возможность установить фиксированное время в тестах, что полезно при работе с датами и временными зонами.

jest.setSystemTime(new Date('2022-01-01'));

6. Группировка тестов с помощью describe

describe() позволяет группировать тесты в логические блоки, что улучшает читаемость и организацию тестов. Это полезно для тестирования различных аспектов одного компонента или модуля.

describe('Math functions', () => {
  test('должен корректно суммировать числа', () => {
    expect(1 + 1).toBe(2);
  });

  test('должен корректно вычитать числа', () => {
    expect(3 - 1).toBe(2);
  });
});

7. Перехват и контроль над ошибками

Jest позволяет перехватывать ошибки, происходящие в тестах, с помощью expect().toThrow().

test('должен выбросить ошибку', () => {
  const func = () => {
    throw new Error('Ошибка');
  };
  expect(func).toThrow('Ошибка');
});

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

test('должен выбросить ошибку с промисом', () => {
  return expect(Promise.reject(new Error('Ошибка'))).rejects.toThrow('Ошибка');
});

8. Конфигурация Jest через API

Jest позволяет конфигурировать фреймворк через различные глобальные объекты и методы. Настройка тестов может быть выполнена с помощью beforeAll(), afterAll(), beforeEach(), afterEach() для выполнения кода до и после тестов или групп тестов.

beforeAll() — вызывается один раз перед запуском всех тестов в файле:

beforeAll(() => {
  console.log('Перед всеми тестами');
});

afterAll() — вызывается один раз после всех тестов:

afterAll(() => {
  console.log('После всех тестов');
});

beforeEach() и afterEach() выполняются до и после каждого теста соответственно.

beforeEach(() => {
  console.log('Перед каждым тестом');
});

afterEach(() => {
  console.log('После каждого теста');
});

9. Параметризация тестов

Jest поддерживает параметризацию тестов, что позволяет запускать одни и те же тесты с различными входными данными. Это можно сделать с помощью test.each():

test.each([
  [1, 1, 2],
  [2, 3, 5],
  [3, 4, 7]
])('суммирует %i и %i до %i', (a, b, expected) => {
  expect(a + b).toBe(expected);
});

Этот подход позволяет значительно уменьшить количество дублирующегося кода в тестах.

10. Асинхронные моки

Jest поддерживает асинхронные моки, которые могут быть использованы в тестах с асинхронными зависимостями. Например, можно мокировать вызовы API или баз данных.

jest.mock('axios');
const axios = require('axios');

test('должен получить данные с API', async () => {
  axios.get.mockResolvedValue({ data: 'response' });
  const response = await axios.get('/data');
  expect(response.data).toBe('response');
});

11. Инструменты для покрытия тестами

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

jest --coverage

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

12. Работа с временными и синхронными ошибками

Jest также имеет средства для работы с временными ошибками, такими как setTimeout или setInterval, а также с синхронными исключениями, что позволяет эмулировать поведение в нестандартных условиях и проверять правильность обработки ошибок.

Jest — это мощный инструмент для тестирования JavaScript-кода, и его API предоставляет гибкие и удобные методы для работы с различными типами тестов, мокированием зависимостей, асинхронными операциями и многим другим.