使用PHPUnit忽略exit()和die()

时间:2014-05-28 15:10:19

标签: php phpunit exit die

首先,标题会显示这是thisthis的副本,但由于几个原因,这些答案对我不起作用,即使我的初始问题是一样的。我将解释原因。

我的问题是:我的代码中有几次我想发送标题和正文然后终止处理。与其他问题不同,我不能使用return或抛出异常(这些显然是为出于不同目的设计的不同函数而不是退出,这不是错误;它只是一些早期的运行时终止具体案例)。

仍然,我想编写运行这些方法的单元测试,确保设置了适当的头文件(找到解决方案here),输出主体是正确的(用$this->expectOutputString()解决 - 方法在测试用例中)然后继续测试。在这两者之间,exit将会发生。

我已经在PHPUnit中尝试了@runInSeparateProcess - 注释,我还检查了test_helpers扩展程序,它有效,但我不想添加其他扩展程序(请注意,测试也将在生产中运行)一行原生PHP代码可以破坏一切。必须有一种更简单的方法而不牺牲最佳实践。

有没有人能很好地解决这个问题?

2 个答案:

答案 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');

这会模拟最高级别的exitdie。您的程序似乎会像以前一样退出,现在可以测试而不会杀死整个测试套件。唯一的问题是如果您在现有代码中捕获其他普通Exception,在这种情况下,您必须修改代码以重新抛出DieException / ExitException个代码,直到它们为止达到顶级。

另一种选择是干净地返回,这可能涉及重写你的很多代码。即,如果你没有在那时退出,为什么你的程序会产生进一步的输出?它应该尽早检查是否需要“提前退出”,然后只需调用该代码并流向程序的自然结束。

如果您必须处理第三方库或其他您不应该或不能更改的代码,这个问题会变得更加困难,但除非他们自己进行单元测试,否则编写测试没有价值理想情况下,您不应该更改第三方代码以避免将来的兼容性问题。一个写得很好的第三方库永远不应该die。它应始终将控制权返回给调用程序,或者抛出可以被捕获的Exception