Jasmine предоставляет мощные инструменты для тестирования исключений
и ошибок, возникающих в коде. В JavaScript обработка исключений
осуществляется через конструкции try...catch или
посредством механизма throw. В контексте тестирования важно
убедиться, что функции выбрасывают ожидаемые ошибки при определённых
условиях. Для этого в Jasmine используются exception
matchers.
Основной matcher для проверки исключений — toThrow(). Он
позволяет убедиться, что вызов функции приводит к выбросу исключения
любого типа:
describe('toThrow example', () => {
it('выбрасывает ошибку', () => {
function problematicFunction() {
throw new Error('Ошибка выполнения');
}
expect(problematicFunction).toThrow();
});
});
Ключевой момент: функция должна передаваться в
expect без вызова, то есть без скобок. Если
написать expect(problematicFunction()), исключение
произойдёт до выполнения expect, и тест не сможет его
поймать.
Для более точной проверки используется toThrowError().
Этот matcher позволяет сопоставлять тип ошибки, текст сообщения или
регулярное выражение:
describe('toThrowError examples', () => {
function throwTypeError() {
throw new TypeError('Некорректный тип данных');
}
it('выбрасывает TypeError', () => {
expect(throwTypeError).toThrowError(TypeError);
});
it('сообщение содержит "тип"', () => {
expect(throwTypeError).toThrowError(/тип/);
});
it('сообщение точно совпадает', () => {
expect(throwTypeError).toThrowError('Некорректный тип данных');
});
});
Особенности toThrowError:
TypeError, ReferenceError) для проверки
типа.toThrowError(TypeError, 'сообщение').Jasmine поддерживает асинхронное тестирование с использованием
async/await или промисов. Исключения в асинхронном коде
требуют другой конструкции. Прямой вызов toThrow() не
работает, поскольку ошибка выбрасывается вне синхронного контекста.
Пример с async/await:
describe('Async exception test', () => {
async function asyncFunction() {
throw new Error('Асинхронная ошибка');
}
it('ловит исключение в async функции', async () => {
await expectAsync(asyncFunction()).toBeRejectedWithError('Асинхронная ошибка');
});
});
Здесь используется специальный matcher для асинхронного
кода — toBeRejectedWithError, который проверяет
промис на отклонение с конкретной ошибкой.
expect напрямую.
Передача вызова (func()) приведёт к ошибке до выполнения
matcher. Всегда передавать саму функцию: expect(func).toThrow,
toThrowError; для промисов и async —
expectAsync(...).toBeRejectedWithError.Иногда полезно проверять состояние объекта или возвращаемое значение до или после выброса исключения:
describe('Exception with state check', () => {
let counter = 0;
function incrementAndThrow() {
counter++;
throw new Error('Ошибка счётчика');
}
it('увеличивает счётчик перед исключением', () => {
expect(incrementAndThrow).toThrowError('Ошибка счётчика');
expect(counter).toBe(1);
});
});
Такой подход обеспечивает не только проверку ошибки, но и правильность побочных эффектов функции.
toThrow() — проверка любого исключения.toThrowError() — проверка типа ошибки и сообщения.expectAsync(...).toBeRejectedWithError() — проверка
ошибок в асинхронных функциях.Exception matchers в Jasmine позволяют создавать точные и надёжные тесты для обработки ошибок, что критично при разработке стабильного и предсказуемого JavaScript-кода.