PHPUnit - как превратить ошибку при вызове метода для не заданного объекта в неудачный тест вместо ошибки - PullRequest
1 голос
/ 29 февраля 2012

У меня есть класс, который использует шаблон Chain of Responsibility. В двух словах, при определенных условиях, если вызывается один из его методов, он передает вызов одному и тому же методу преемника (он и преемник используют один и тот же интерфейс).

Пример:

catch(PDOException $exception)
    {
        if(isset($this->successor))
        {
            $this->successor->log($log);
        }
    }

Обычно, если преемник был установлен, ему дается вызов. Если нет, то ничего не происходит.

В данный момент в моем модульном тесте у меня есть два теста: в одном из них установлен преемник, и метод вызывается при правильных условиях для запуска вызова преемника. Преемник - это макет, и я могу проверить, что вызывается правильный метод.

Теперь, перед написанием оператора if, я продублировал тот же тест, но удалил код, который устанавливает объект-преемник. Когда я запускаю тест, не удивительно, что тест останавливается с ошибкой, потому что SUT пытается вызвать метод для объекта, который не существует.

Когда я реализую код (как выше), все тесты проходят нормально.

Хотя я несчастен. Я следую методологии TDD и хочу, чтобы я смог увидеть неудачный тест, прежде чем писать код, а не ошибку.

Как я могу провести рефакторинг, чтобы я мог сначала пройти неудачный тест вместо ошибки?

Ответы [ 2 ]

2 голосов
/ 29 февраля 2012

К сожалению, это неизбежно.PHP вызывает фатальную ошибку (E_FATAL_ERROR), которая убивает процесс.PHPUnit не может перехватить его, чтобы вызвать ошибку или сбой, также как и ваш код.

$ php -r 'try { $o = null; $o->foo(); } catch (Exceptiion $e) { echo "fail"; }'

Fatal error: Call to a member function foo() on a non-object in Command line code on line 1

Самое большее, что вы можете сделать, это обнаружить ошибку в функции отключения и вывести некоторые диагностические данные.Нет способа восстановиться после фатальной ошибки.: (

Что касается TDD, я считаю, что цель состоит в том, чтобы написать как можно больше тестового кода, чтобы ваши тесты не проходили . Это может показаться тонким различием, но это означает неудачу (F) или ошибка (E), или умрите (прекратите работу). Как только вы попадете туда, напишите код, чтобы тесты прошли успешно.

0 голосов
/ 29 февраля 2012

Поместите свои юнит-тесты в блок TRY-CATCH.Если вы поймали исключение, вы можете преобразовать его в ошибку:

try {
    ...testing
} catch (Exception $e) {
    $this->assertTrue(false, $e->getMessage());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...