使用 PHPUnit 3.6 我试图在下面的控制器类中测试exec()
方法。这种方法做了两件事:
(简化)源代码如下所示:
abstract class CLIController extends Controller
{
/* irrelevant class details here */
public function exec()
{
$action = ! empty($this->opts->args[0])
? $this->opts->args[0]
: $this->default_action;
if ( ! $action || ! is_callable(array($this, $action))) {
$msg = 'Invalid controller action specified';
throw new LogicException($msg);
} else {
$this->$action(); // <---- trying to get code coverage on this line!
}
}
}
我无法弄清楚如何覆盖这部分代码:
} else {
$this->$action();
}
因为我不确定如何(或者甚至可能)测试一个方法的调用,该方法的名称在抽象类的上下文中是未知的。 再次:要调用的方法在子类中声明。通常我会模拟一个抽象方法,但在这种情况下我不能,因为该方法尚不存在 - 它将由子类指定。
exec()
在它应该发生异常时抛出异常,我知道该行的正确运行取决于PHP的正常运行。这是否有必要首先测试它??? exec()
功能。 我真的很感激有关如何最好地继续这里的任何指导。提前谢谢。
答案 0 :(得分:5)
我不同意你的规定,“创建一个具体的子类只是为了测试一个抽象的父母,这不是一个好主意。”我在测试抽象类时经常这样做,并且通常在测试之后命名具体的子类以使其清楚。
class CLIControllerTest extends PHPUnit_Framework_TestCase
{
public function testCallsActionMethod()
{
$controller = new CLIControllerTest_WithActionMethod(...);
// set $controller->opts->args[0] to 'action'
$controller->exec();
self::assertTrue($controller->called, 'Action method was called');
}
}
class CLIControllerTest_WithActionMethod extends CLIController
{
public $called = false;
public function action() {
$this->called = true;
}
}
进行此测试的代码非常简单,可以通过检查轻松验证。
我很好奇,为什么要使用is_callable
代替method_exists
来避免创建数组?这可能只是个人偏好,但我想知道是否存在任何语义差异。