Как вы используете PHPUnit для проверки функции, если эта функция должна убивать PHP?
По существу у меня есть метод класса killProgram, который предназначен для отправки перенаправления hTTP, а затем для удаления PHP.
Как я должен проверить это? Когда я запускаю phpunit, он ничего не возвращает для этого теста и полностью закрывается.
Сейчас я рассматриваю возможность использования функции killProgram для исключения, которое не должно обрабатываться, что позволило бы мне утверждать, что было создано исключение.
Есть ли лучший способ?
Ответы
Ответ 1
Поскольку каждый тест выполняется одним и тем же процессом PHPUnit, если вы используете exit/die в своем PHP-коде, вы все убьете - как вы заметили ^^
Итак, вы должны найти другое решение, да - как возвращение вместо смерти; или бросать исключение (вы можете проверить, не вызвал ли какой-либо проверенный код ожидаемое исключение).
Может быть, PHPUnit 3.4 и он --process-isolation
switch (см. При необходимости выполнить каждый тест с помощью отдельного процесса PHP) может help (не имея все умирающего), но вы все равно не сможете получить результат теста, если PHPUnit не получит контроль.
У меня была эта проблема несколько раз; решает его, возвращаясь, а не умирая - даже возвращаясь несколько раз, если нужно, чтобы вернуться "достаточно высоко" в стек вызовов ^ ^
В конце концов, я полагаю, у меня больше нет "смерти" в моем приложении... Вероятно, лучше, когда думаешь о MVC, кстати.
Ответ 2
Это, очевидно, старый вопрос, но моим предложением было бы переместить код 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
, и вам не нужно беспокоиться о завершении script, если вы не сможете его поймать.
Ваш тест будет выглядеть примерно так:
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();
}
}
Я не тестировал код, но должен быть близок к рабочему состоянию.
Ответ 3
Нет необходимости изменять код, чтобы проверить его, вы можете просто использовать set_exit_overload()
(предоставленный test_helpers
от того же автора, что и PHPUnit).
Ответ 4
Я понимаю, что вы уже приняли ответ для этого, и это старый вопрос, но я полагаю, что это может быть полезно для кого-то, поэтому здесь идет:
Вместо использования die()
вы можете использовать throw new RuntimeException()
(или собственный класс исключений), который также остановит выполнение программы (хотя и по-другому) и использует PHPUnit setExpectedException()
, чтобы поймать его. Если вы хотите, чтобы ваш script до die()
, когда это исключение встречается, абсолютно ничего не печатать на уровне пользователя, посмотрите set_exception_handler()
.
В частности, я думаю о сценарии, в котором вы помещаете set_exception_handler()
-call в файл начальной загрузки, который тесты не используют, поэтому обработчик не будет запускать его независимо от сценария, поэтому ничего вмешивается в работу с обработкой исключительных ошибок PHPUnit.
Ответ 5
Это относится к набору проблем, с которыми я получаю некоторый старый код для прохождения теста. Поэтому я придумал класс Testable, подобный этому...
class Testable {
static function exitphp() {
if (defined('UNIT_TESTING')) {
throw new TestingPhpExitException();
} else {
exit();
}
}
}
Теперь я просто заменяю вызовы на exit() с помощью Testable:: exitphp().
Если он тестируется, я просто определяю UNIT_TESTING, в производстве я этого не делаю. Похоже на простой макет.
Ответ 6
Вы можете убить скрипт или вызвать исключение, в зависимости от значения переменной среды...
Таким образом, вы убиваете на производстве или создаете исключение в тестовой среде.
Любой призыв умереть или выйти, убивает весь процесс...
Это должен был быть комментарий, но я не могу комментировать уровень моих очков репутации.