Перейти к основному содержимому

Функции, которые могут завершиться ошибкой

Функция, которой могут передать некорректные данные, обязана сообщить об этом. Обычный способ — выбросить ошибку: при успехе функция возвращает результат, при неудаче выбрасывает Error с объяснением, что пошло не так.

Тест для такой функции должен проверять оба пути: корректные данные возвращают правильное значение и не приводят к ошибке, а некорректные данные действительно вызывают ошибку — функция, которая молча принимает некорректные данные, это тоже ошибка.

assert.throws(fn) — это проверка для «плохого» пути. Для функции, которая возвращает промис, та же проверка записывается как assert.rejects(fn) и ожидается через await.


«Хороший» путь

Для корректных входных данных ничего дополнительного писать не нужно. Вызовите функцию, затем сравните значение. Если вызов вместо этого выбросит ошибку, она сама завершит тест, и отчёт покажет эту ошибку — проверять её заранее не нужно.

Корректные данные, без ошибки

safeDivide(10, 2) должна вернуть 5 и не должна выбрасывать ошибку. Сначала идёт вызов; неожиданная ошибка завершила бы тест прямо здесь. И только потом сравнивается значение.

Prompt
Напишите файл теста на TypeScript с функцией safeDivide, которая возвращает число и выбрасывает RangeError, когда делитель равен нулю. Проверьте «хороший» путь: safeDivide(10, 2) должна вернуть 5 и не должна выбрасывать ошибку. Покажите вывод успешного прохождения.
Вывод: программа на TypeScript и захваченный вывод
Valid input, no error

«Плохой» путь

Вторая половина контракта: некорректные данные должны приводить к ошибке. assert.throws принимает небольшую функцию, которая выполняет вызов, запускает её и считает тест неуспешным, если ошибка не была выброшена.

Можно также указать, какая именно ошибка должна быть выброшена. Передача класса ошибки вторым аргументом делает тест неуспешным, если выброшена ошибка другого вида.

Некорректные данные должны вызывать ошибку

Деление на ноль обязано завершиться ошибкой. assert.throws вызывает safeDivide(10, 0) и требует RangeError. Если бы функция вместо этого вернула число, тест был бы неуспешным — она приняла данные, которые должна была отвергнуть.

Prompt
Напишите тест на TypeScript для «плохого» пути функции safeDivide: вызов с делителем 0 должен выбрасывать ошибку. Используйте assert.throws с RangeError в качестве ожидаемой ошибки. Покажите вывод успешного прохождения.
Вывод: программа на TypeScript и захваченный вывод
Bad input must throw

Таблица с wantErr

Оба пути помещаются в один табличный тест: добавьте каждому случаю поле wantErr, которое говорит, ожидается ли ошибка. Поле want необязательное, потому что у случая с ошибкой нет значения для сравнения.

Каждый подтест сначала смотрит на wantErr. Ожидаемые ошибки проверяются через assert.throws и на этом заканчиваются; остальные случаи сравнивают значение как обычно.

Хорошие и плохие случаи в одной таблице

Четыре случая: три обычных деления и одно деление на ноль с wantErr: true. Один цикл покрывает весь контракт функции, и все четыре подтеста проходят успешно.

Prompt
Напишите табличный тест на TypeScript для функции safeDivide, где у каждого случая есть имя, два входных значения, необязательное ожидаемое значение и булево поле wantErr. Используйте подтесты t.test с await; ожидаемую ошибку проверяйте через assert.throws, а для остальных случаев сравнивайте значение. Включите три обычных случая и одно деление на ноль. Покажите вывод.
Вывод: программа на TypeScript и захваченный вывод
Good and bad cases in one table