Jest предоставляет мощные инструменты для тестирования асинхронного кода, включая работу с промисами. В этой главе рассматриваются основные подходы и техники для тестирования промисов, а также особенности работы с асинхронными функциями в Jest.
Промисы в JavaScript представляют собой объекты, которые асинхронно возвращают результат выполнения операции. В Jest тестирование промисов требует особого внимания, поскольку тесты должны правильно обрабатывать асинхронные операции.
Jest позволяет тестировать асинхронные функции с помощью таких
методов, как resolves, rejects,
async/await, а также возможности работы с таймерами.
resolves и
rejectsJest предоставляет специальные матчеры resolves и
rejects, которые позволяют упростить проверку результатов
промисов.
Если асинхронная функция возвращает промис, который должен быть
выполнен успешно, используется матчар resolves.
Пример:
test('проверка успешного выполнения промиса', () => {
const promise = Promise.resolve('успех');
return expect(promise).resolves.toBe('успех');
});
В этом примере промис разрешается значением “успех”, и тест проверяет, что результат выполнения промиса соответствует ожидаемому значению.
Если промис должен быть отклонен с ошибкой, используется матчар
rejects.
Пример:
test('проверка отклонения промиса', () => {
const promise = Promise.reject(new Error('ошибка'));
return expect(promise).rejects.toThrow('ошибка');
});
Здесь промис отклоняется с ошибкой, и тест проверяет, что ошибка соответствует ожидаемой.
async/await для тестирования промисовИспользование синтаксиса async/await позволяет
значительно упростить работу с асинхронными функциями. Вместо того чтобы
явно указывать return в тестах, можно использовать
await для ожидания выполнения промиса и проверки
результата.
Пример:
test('проверка успешного выполнения промиса с async/await', async () => {
const result = await Promise.resolve('успех');
expect(result).toBe('успех');
});
В этом случае использование await позволяет ожидать
результат промиса и затем проверять его через expect.
Иногда в тестах требуется работать с таймерами или асинхронными
операциями, которые выполняются через задержку. Jest предоставляет
встроенные методы для работы с таймерами —
jest.useFakeTimers() и
jest.advanceTimersByTime(). Они позволяют управлять
временем в тестах, не дожидаясь реальных задержек.
Пример с использованием таймеров:
test('проверка работы с таймерами', () => {
jest.useFakeTimers();
const mockCallback = jest.fn();
setTimeout(() => mockCallback('выполнено'), 1000);
jest.advanceTimersByTime(1000);
expect(mockCallback).toHaveBeenCalledWith('выполнено');
});
В этом примере используется функция
jest.useFakeTimers(), которая позволяет управлять временем
в тестах. С помощью jest.advanceTimersByTime() можно
“перемотать” время на заданное количество миллисекунд и проверить, что
колбэк был вызван.
В случае, когда тестируемая функция работает с несколькими промисами,
Jest позволяет удобно тестировать их выполнение параллельно. Например,
можно использовать Promise.all для проверки нескольких
промисов одновременно.
Пример:
test('параллельное выполнение промисов', async () => {
const promise1 = Promise.resolve('результат 1');
const promise2 = Promise.resolve('результат 2');
const results = await Promise.all([promise1, promise2]);
expect(results).toEqual(['результат 1', 'результат 2']);
});
Здесь оба промиса выполняются параллельно, и тест проверяет, что оба промиса разрешаются с правильными значениями.
Когда в асинхронном коде может возникнуть ошибка, важно корректно ее
обработать. В Jest ошибки, возникающие в промисах, можно обрабатывать с
помощью try/catch.
Пример:
test('обработка ошибки в промисе', async () => {
try {
await Promise.reject(new Error('ошибка'));
} catch (e) {
expect(e).toEqual(new Error('ошибка'));
}
});
Здесь мы используем try/catch для того, чтобы поймать
ошибку, отклоненную промисом, и проверить, что она соответствует
ожидаемой.
Jest позволяет комбинировать различные методы для более сложных тестов. Например, можно проверять как результаты успешных, так и отклоненных промисов с использованием разных матчеров в одном тесте.
Пример:
test('комбинированное тестирование успешных и неудачных промисов', async () => {
const successPromise = Promise.resolve('успех');
const failurePromise = Promise.reject(new Error('ошибка'));
await expect(successPromise).resolves.toBe('успех');
await expect(failurePromise).rejects.toThrow('ошибка');
});
Этот тест проверяет как успешное выполнение промиса, так и его отклонение в одном тесте с помощью асинхронных ожиданий.
Чистота тестов: При тестировании асинхронного
кода важно, чтобы каждый тест был независимым и не влиял на другие.
Поэтому рекомендуется использовать методы очистки, такие как
jest.clearAllMocks(), для сброса состояния между
тестами.
Не используйте done() без
необходимости: В Jest можно использовать коллбек
done() для асинхронных тестов, но в большинстве случаев
лучше использовать async/await, так как это делает код
более читаемым и упрощает управление асинхронностью.
Ожидайте результата до конца: Использование
await гарантирует, что тест завершится только после
выполнения всех асинхронных операций, что помогает избежать ошибок,
связанных с не до конца выполненными промисами.
Обработка ошибок: Всегда учитывайте, что промисы могут быть отклонены. Тесты, которые не проверяют ошибки, могут пропустить важные исключения.
Тестирование промисов в Jest предоставляет гибкие и удобные инструменты для проверки асинхронных функций, что делает процесс тестирования более эффективным и надежным.