首先,标题会显示这是this或this的副本,但由于几个原因,这些答案对我不起作用,即使我的初始问题是一样的。我将解释原因。
我的问题是:我的代码中有几次我想发送标题和正文然后终止处理。与其他问题不同,我不能使用return
或抛出异常(这些显然是为出于不同目的设计的不同函数而不是退出,这不是错误;它只是一些早期的运行时终止具体案例)。
仍然,我想编写运行这些方法的单元测试,确保设置了适当的头文件(找到解决方案here),输出主体是正确的(用$this->expectOutputString()
解决 - 方法在测试用例中)然后继续测试。在这两者之间,exit
将会发生。
我已经在PHPUnit中尝试了@runInSeparateProcess
- 注释,我还检查了test_helpers扩展程序,它有效,但我不想添加其他扩展程序(请注意,测试也将在生产中运行)一行原生PHP代码可以破坏一切。必须有一种更简单的方法而不牺牲最佳实践。
有没有人能很好地解决这个问题?
答案 0 :(得分:4)
我在bootstrap中添加了一个变量,我可以在代码中引用一个IF,在那些我不需要退出的极少数情况下。
define ('PHPUNIT_RUNNING', 1);
正常计划:
if(! @PHPUNIT_RUNNING === 1 )
{
exit;
}
PHPUnit没有被定义为规则,因此在PHP执行时会生成一个警告(我们用@隐藏。然后代码将在不处于测试模式时执行我们想要的操作。这是在主代码之后添加的编写时我们将PHPUnit测试添加到现有项目中,而不是执行TDD。
请注意:
我们尽可能少地解决遗留问题,否则我们会像其他人一样建议并抛出异常或将数据返回到父函数。
答案 1 :(得分:2)
我刚刚测试了以下想法:
ExitException.php:
<?php
class DieException extends Exception {} // for those people who like die as well as exit
class ExitException extends Exception {}
entrypoint.php:
<?php
require_once 'ExitException.php';
try {
require 'main_code.php';
run_main_code();
}
catch (DieException $e) {
return $e->getMessage();
}
catch (ExitException $e) {
return $e->getMessage();
}
之后的几个include
:
deepcode.php
<?php
throw new ExitException('Exiting normally');
这会模拟最高级别的exit
或die
。您的程序似乎会像以前一样退出,现在可以测试而不会杀死整个测试套件。唯一的问题是如果您在现有代码中捕获其他普通Exception
,在这种情况下,您必须修改代码以重新抛出DieException
/ ExitException
个代码,直到它们为止达到顶级。
另一种选择是干净地返回,这可能涉及重写你的很多代码。即,如果你没有在那时退出,为什么你的程序会产生进一步的输出?它应该尽早检查是否需要“提前退出”,然后只需调用该代码并流向程序的自然结束。
如果您必须处理第三方库或其他您不应该或不能更改的代码,这个问题会变得更加困难,但除非他们自己进行单元测试,否则编写测试没有价值理想情况下,您不应该更改第三方代码以避免将来的兼容性问题。一个写得很好的第三方库永远不应该die
。它应始终将控制权返回给调用程序,或者抛出可以被捕获的Exception
。