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

Функции, которые бросают исключения

Многие функции PHP отклоняют некорректный ввод, бросая исключение: при успехе они возвращают результат, при ошибке бросают исключение и вообще ничего не возвращают.

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


Успешный путь

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

Корректный ввод, без исключения

safeDivide(10, 2) должна вернуть 5.0 и ничего не бросить. Достаточно одного assertSame — неожидаемое исключение провалит тест без всякого дополнительного кода.

Prompt
Напиши файл теста PHPUnit с функцией safeDivide, которая возвращает float и бросает InvalidArgumentException при делении на ноль. Напиши тест для успешного пути: safeDivide(10, 2) должна вернуть 5.0, проверка — один вызов assertSame; неожидаемое исключение само по себе провалит тест. Покажи вывод phpunit.
Вывод: PHP-скрипт
Valid input, no exception

Ошибочный путь

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

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

Некорректный ввод должен бросить исключение

Деление на ноль обязано завершиться ошибкой. Тест ожидает InvalidArgumentException; safeDivide(10, 0) бросает его, поэтому запуск сообщает OK (1 test, 1 assertion). Если бы safeDivide здесь вернула значение, тест провалился бы.

Prompt
Напиши тест PHPUnit для ошибочного пути функции safeDivide: вызов с делителем 0 должен бросить исключение. Объяви ожидание через expectException до вызова. Покажи вывод phpunit.
Вывод: PHP-скрипт
Bad input must throw

Таблица с полем throws

Оба пути укладываются в один data-провайдер: добавьте каждой строке поле throws, которое говорит, ожидается ли исключение.

Тестовый метод сначала проверяет это поле — для строки с исключением он объявляет expectException, вызывает функцию и выходит. Для успешных строк он сравнивает значение как обычно.

Успешные и ошибочные случаи в одной таблице

Четыре строки: три обычных деления и одно деление на ноль, где throws равно true. Один тестовый метод покрывает весь контракт функции — при запуске с --testdox все четыре случая проходят.

Prompt
Напиши тест PHPUnit с data-провайдером для функции safeDivide, где каждая строка содержит имя, два входных значения, ожидаемое значение и флаг throws. Для строк с исключением объяви expectException и вызови функцию; значение сравнивай только для строк без ожидаемого исключения. Включи три обычных случая и одно деление на ноль. Покажи вывод phpunit --testdox.
Вывод: PHP-скрипт
Good and bad cases in one table