Jest предоставляет обширный программный API, который позволяет не только запускать тесты, но и управлять их выполнением, конфигурировать среду тестирования, а также взаимодействовать с различными аспектами фреймворка. Основной задачей программного API является обеспечение гибкости и удобства для тестирования в реальных проектах. Рассмотрим основные элементы и возможности API Jest.
test() — это основной метод для
написания тестов в Jest. Он позволяет задать описание теста и функцию,
которая будет выполнена.
test('должен корректно суммировать два числа', () => {
expect(1 + 1).toBe(2);
});
it() является алиасом для
test(), и поведение этих методов идентично. Рекомендуется
использовать оба метода в зависимости от предпочтений.
it('должен корректно суммировать два числа', () => {
expect(1 + 1).toBe(2);
});
Jest предоставляет мощные механизмы для утверждений, которые называются Matchers. Они используются для проверки значений, которые возвращает тестируемый код.
Пример:
expect(1 + 1).toBe(2); // Проверка на равенство
expect([1, 2, 3]).toContain(2); // Проверка на наличие элемента
Основные матчеры:
toBe(value) — проверка на строгое равенство.toEqual(value) — проверка на глубокое равенство
объектов.toContain(value) — проверка на наличие значения в
коллекции.toHaveBeenCalled() — проверка на вызов функции.Асинхронные тесты в 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();
});
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')
}));
Время играет важную роль в тестах, например, при проверке таймеров
или работы с датами. 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'));
describedescribe() позволяет группировать тесты
в логические блоки, что улучшает читаемость и организацию тестов. Это
полезно для тестирования различных аспектов одного компонента или
модуля.
describe('Math functions', () => {
test('должен корректно суммировать числа', () => {
expect(1 + 1).toBe(2);
});
test('должен корректно вычитать числа', () => {
expect(3 - 1).toBe(2);
});
});
Jest позволяет перехватывать ошибки, происходящие в тестах, с помощью
expect().toThrow().
test('должен выбросить ошибку', () => {
const func = () => {
throw new Error('Ошибка');
};
expect(func).toThrow('Ошибка');
});
Для асинхронных функций также можно использовать
rejects и
resolves:
test('должен выбросить ошибку с промисом', () => {
return expect(Promise.reject(new Error('Ошибка'))).rejects.toThrow('Ошибка');
});
Jest позволяет конфигурировать фреймворк через различные глобальные
объекты и методы. Настройка тестов может быть выполнена с помощью
beforeAll(), afterAll(),
beforeEach(), afterEach() для
выполнения кода до и после тестов или групп тестов.
beforeAll() — вызывается один раз перед
запуском всех тестов в файле:
beforeAll(() => {
console.log('Перед всеми тестами');
});
afterAll() — вызывается один раз после
всех тестов:
afterAll(() => {
console.log('После всех тестов');
});
beforeEach() и
afterEach() выполняются до и после каждого
теста соответственно.
beforeEach(() => {
console.log('Перед каждым тестом');
});
afterEach(() => {
console.log('После каждого теста');
});
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);
});
Этот подход позволяет значительно уменьшить количество дублирующегося кода в тестах.
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');
});
Jest поддерживает генерацию отчетов о покрытии тестами с помощью
флага --coverage. Это позволяет выявлять участки кода,
которые не были покрыты тестами.
jest --coverage
После выполнения тестов Jest создает отчет о покрытии, который включает информацию о том, сколько строк кода и функций было покрыто тестами.
Jest также имеет средства для работы с временными ошибками, такими
как setTimeout или
setInterval, а также с синхронными
исключениями, что позволяет эмулировать поведение в нестандартных
условиях и проверять правильность обработки ошибок.
Jest — это мощный инструмент для тестирования JavaScript-кода, и его API предоставляет гибкие и удобные методы для работы с различными типами тестов, мокированием зависимостей, асинхронными операциями и многим другим.