Основные тесты, которые нужно писать, это тесты на успешные сценарии работы. Но в некоторых ситуациях код должен возвращать ошибки и их тоже бывает нужно проверять. Под ошибками понимаются ситуации, в которых код выбрасывает исключение. В чем их особенность? Посмотрите на тест:
test('boom!', () => {
try {
functionWithException(0);
} catch (e) {
expect(e).not.toBeNull();
}
});
Этот код пытается протестировать ситуацию, при которой функция functionWithException()
выбрасывает исключение, если ей передать 0. Как вы думаете, этот тест проверит, что функция действительно порождает исключение?
Правильный ответ — нет. Если функция functionWithException()
не выбросит исключение, то тест пройдет, так как код не попадет в блок catch
.
Документация Jest предлагает свой способ тестирования таких ситуаций. Jest позволяет указать количество утверждений, которые должны выполниться в тесте. Если этого не происходит, то Jest сообщает об ошибке:
test('boom!', () => {
// Количество утверждений, которые должны быть запущены в этом тесте
expect.assertions(1);
try {
functionWithException(0);
} catch (e) {
expect(e).not.toBeNull();
}
});
Этот способ крайне опасен. Он порождает хрупкие тесты, которые завязаны на то, как они написаны. Если вы захотите добавить новое утверждение, то тест провалится и придется его править. Вам всегда придется следить за тем, чтобы это число было правильным. Не используйте этот подход, чем больше контекстной зависимости, тем сложнее разобраться в коде и проще наделать ошибок.
И наконец-то мы подобрались к правильному способу. В Jest есть матчер, который самостоятельно отлавливает исключение и проверяет, что оно вообще было сгенерировано.
test('boom!', () => {
expect(() => {
functionWithException(0);
}).toThrow();
});
Главная особенность этого матчера в том, что он принимает на вход функцию, которая вызывается внутри. Благодаря этому, он может самостоятельно отследить появление исключения. Этот код не содержит неявного состояния и лишних проверок, он делает ровно то, что нужно делать и не требует от нас слишком много. Более того, теоретически возможен тест, в котором делается сразу несколько проверок на различные исключения. Это значительно сложнее провернуть с предыдущими способами.
Иногда важно не просто поймать исключение, но и убедиться в том, что это ожидаемое исключение. Сделать это можно, передав в матчер toThrow()
строку, которая должна присутствовать в сообщении исключения.
test('boom!', () => {
expect(() => {
functionWithException(0);
}).toThrow('divide by zero');
});
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.