Как вы используете PHPUnit для проверки функции, если эта функция должна убивать PHP?

По сути, у меня есть метод класса 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, в производстве я этого не делаю. Похоже на простой макет.