По сути, у меня есть метод класса killProgram, который предназначен для отправки перенаправления hTTP, а затем для удаления PHP.
Как я должен проверить это? Когда я запускаю phpunit, он ничего не возвращает для этого теста и полностью закрывается.
Прямо сейчас я подумываю о том, что функция killProgram выдает исключение, которое не должно обрабатываться, что позволит мне утверждать, что было создано исключение.
Есть ли способ лучше?
Поскольку каждый тест выполняется одним и тем же процессом PHPUnit, если вы используете exit / die в своем PHP-коде, вы убьете все – как вы заметили ^^
Итак, вы должны найти другое решение, да – как возвращение вместо смерти; или выброс исключения (вы можете проверить, не вызвал ли какой-либо проверенный код ожидаемое исключение) .
Возможно, PHPUnit 3.4 и это --process-isolation
переключатель --process-isolation
(см. Опционально выполнить каждый тест с использованием отдельного процесса PHP ) может помочь (не имея все умирающего) , но вы все равно не сможете получить результат теста, если PHPUnit не получает контроль.
У меня была эта проблема несколько раз; решает его, возвращаясь, а не умирая – даже возвращаясь несколько раз, если нужно, чтобы вернуться «достаточно высоко» в стек вызовов ^ ^
В конце концов, я полагаю, у меня больше нет «смерти» в моем приложении … Вероятно, это лучше, когда мы думаем о MVC, кстати.
Это, очевидно, старый вопрос, но моим предложением было бы переместить код, который умеет die()
, в отдельный метод, который вы можете затем высмеять.
В качестве примера вместо этого:
class SomeClass { public function do() { exit(1); // or die('Message'); } }
сделай это:
class SomeClass { public function do() { $this->terminate(123); // or $this->terminate('Message'); } protected function terminate($code = 0) { exit($code); } // or protected function terminate($message = '') { die($message); } }
Таким образом, вы можете легко высмеять метод terminate
и вам не нужно беспокоиться о завершении сценария, если вы не сможете его поймать.
Ваш тест будет выглядеть примерно так:
class SomeClassTest extends \PHPUnit_Framework_TestCase { /** * @expectedExceptionCode 123 */ public function testDoFail() { $mock = $this->getMock('SomeClass'); $mock->expects($this->any()) ->method('terminate') ->will($this->returnCallback(function($code) { throw new \Exception($code); })); // run to fail $mock->do(); } }
Я не тестировал код, но должен быть близок к рабочему состоянию.
Нет необходимости менять код, чтобы проверить его, вы можете просто использовать set_exit_overload()
(предоставленный test_helpers
от того же автора, что и PHPUnit).
Я понимаю, что вы уже приняли ответ для этого, и это старый вопрос, но я полагаю, что это может быть полезно для кого-то, так вот:
Вместо использования die()
вы можете использовать throw new RuntimeException()
(или собственный класс исключений), который также остановит выполнение программы (хотя и по-другому) и будет использовать setExpectedException()
PHPUnit, чтобы поймать ее. Если вы хотите, чтобы ваш скрипт die()
когда это исключение встречается, печать абсолютно ничего на уровне пользователя, посмотрите на set_exception_handler()
.
В частности, я думаю о сценарии, в котором вы помещаете set_exception_handler()
-call в файл начальной загрузки, который не использует тесты, поэтому обработчик не будет запускать его независимо от сценария, поэтому ничто не мешает PHPUnit'у Собственная обработка исключений.
Это связано с множеством проблем, с которыми я получаю некоторый старый код для прохождения теста. Итак, я придумал класс Testable, подобный этому …
class Testable { static function exitphp() { if (defined('UNIT_TESTING')) { throw new TestingPhpExitException(); } else { exit(); } } }
Теперь я просто заменяю вызовы exit () с помощью Testable :: exitphp ().
Если это испытание, я просто определяю UNIT_TESTING, в производстве я этого не делаю. Похоже на простой макет.