Тестирование async функций с ожидаемыми ошибками в Jest

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

JS
Скопировать код
await expect(asyncFunction()).rejects.toThrow('Ой! Хьюстон, у нас проблемы');

Это ваш путеводитель по использованию метода expect().rejects.toThrow() в Jest для проверки корректности обработки ошибок в асинхронных функциях.

Кинга Идем в IT: пошаговый план для смены профессии

Детально разбираем тестирование асинхронных ошибок

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

Стрелочная или асинхронная функция

Отлавливание асинхронных ошибок осуществляется с помощью стрелочной функции или асинхронной функции:

JS
Скопировать код
// Заворачиваем в стрелочную функцию
await expect(() => asyncFunction()).rejects.toThrow('Ошибка с ID 42');

// Или используем асинхронную функцию
await expect(asyncFunction).rejects.toThrow('Ошибка с ID 42');

Проверяем тип ошибки

Убедитесь в достоверности тестов: проверяем, генерируется ли обычный Error, или используется специализированный класс ошибок:

JS
Скопировать код
// Проверяем генерацию стандартной ошибки
await expect(asyncFunction()).rejects.toBeInstanceOf(Error);

// И еще проверяем генерацию пользовательской ошибки
await expect(asyncFunction()).rejects.toBeInstanceOf(CustomError);

Не ограничивайтесь лишь классификацией ошибок – проверяйте текст сообщения или даже экземпляры ошибок:

JS
Скопировать код
// Проверяем текст ошибки с использованием регулярных выражений
await expect(asyncFunction()).rejects.toThrowError(/скрытая смертельная опасность/);

Подсчитываем количество утверждений в тесте

Примените expect.assertions(n), где n означает количество ожидаемых утверждений в тесте. Это позволяет контролировать количество проверок в тесте и избегает утраты нужных утверждений.

JS
Скопировать код
test('асинхронная функция генерирует ошибку', async () => {
  expect.assertions(1); // контролируем число утверждений
  await expect(asyncFunction()).rejects.toBeInstanceOf(CustomError);
});

Без ложных срабатываний

Следите, бывает ли такое, что Промис ошибочно переходит в resolve состояние:

JS
Скопировать код
test('промис заканчивает работу с ошибкой', async () => {
  await expect(somePromise()).rejects.toThrow(); // У нас нет ожиданий насчет resolve.
});

Визуализация

Можно аналогично представить процесс обработки асинхронных ошибок, как движение по автомагистрали:

Markdown
Скопировать код
| Этапы асинхронного теста | Дорога     | Обработка исключений |
|-------------------------|------------|----------------------|
| 🏃‍♂️ Начало теста      | 🛣️ Магистраль  | 🚧 Препятствие       |
| 🔄 Ожидание асинхронности | 🕒 Затор    | 🚔 Контроль           |
| 🎯 Проверка исключения   | 📍 Финиш     | 👮‍♂️ Досмотр          |

Проверяющий двигается к контрольному пункту:

Markdown
Скопировать код
🚗💨 Неуклонно приближается к проверке.
🚧🚔 Настороженности, препятствие (исключение) впереди.
👮‍♂️📋 Соответствие ожидаемому – тест пройден успешно.

Важно! Необходимо понимать логику работы асинхронного кода и правильное решение ошибок.

Тестирование нескольких ошибок параллельно

Почему останавливаться на одной проверке? Проводите множественные тесты параллельно:

JS
Скопировать код
test('множественная проверка исключений', async () => {
  await expect(asyncFunction()).rejects.toMatchObject({
    name: 'EvilError', // это имя ошибки
    message: 'Я неизбежен', // и описание ошибки
  });
});

Для более точного сопоставления используйте регулярные выражения:

JS
Скопировать код
// Регулярное выражение для поиска текста ошибки
await expect(asyncFunction()).rejects.toThrow(/неизбежен/i);

Взаимодействие с .catch() без async/await

Предпочитаете работать с promises и .catch()? Вот подходящий пример:

JS
Скопировать код
somePromise()
  .then(() => {
    throw new Error('Ой! Мы разрешили то, что должны были отклонить');
  })
  .catch(error => expect(error).toBeInstanceOf(ExpectedError)); // Ловим промисы с помощью `.catch()`

Полезные материалы

  1. Тестирование асинхронного кода в Jest — подробное руководство по работе с async/await в Jest для тестов асинхронного кода.
  2. Expect в Jest — описание матчера .toThrowError(), используемого для поиска ошибок в тестах.
  3. Матчеры в Jasmine — использование методов Jasmine для ожидания ошибок при вызове функции.
  4. async function в JavaScript — подробно о асинхронных функциях и их применении в JavaScript.
  5. Работа с промисами в JavaScript — руководство по обработке ошибок в промисах.
  6. Async/await — простое введение в синтаксис async/await и работу с промисами.
  7. Mocha — написание тестов для асинхронного кода с использованием Mocha.