PHP单元测试:是否可以测试致命错误?

时间:2011-01-20 23:21:40

标签: php unit-testing singleton simpletest fatal-error

FWIW我正在使用SimpleTest 1.1alpha。

我有一个单例类,我想编写一个单元测试,通过尝试实例化类(它有一个私有构造函数)来保证该类是一个单例。

这显然会导致致命错误:

  

致命错误:调用私有FrontController :: __ construct()

有没有办法“捕获”致命错误并报告通过的测试?

3 个答案:

答案 0 :(得分:12)

没有。致命错误会停止执行脚本。

并没有必要以这种方式测试单身人士。如果您坚持检查构造函数是否为私有,则可以使用ReflectionClass:getConstructor()

public function testCannotInstantiateExternally()
{
    $reflection = new \ReflectionClass('\My\Namespace\MyClassName');
    $constructor = $reflection->getConstructor();
    $this->assertFalse($constructor->isPublic());
}

另一件需要考虑的事情是,Singleton类/对象是TTD的一个障碍,因为它们难以模拟。

答案 1 :(得分:5)

这是Mchl答案的完整代码段,因此人们不必浏览文档......

public function testCannotInstantiateExternally()
{
    $reflection = new \ReflectionClass('\My\Namespace\MyClassName');
    $constructor = $reflection->getConstructor();
    $this->assertFalse($constructor->isPublic());
}

答案 2 :(得分:3)

您可以使用像PHPUnit的进程隔离这样的概念。

这意味着测试代码将在php的子进程中执行。这个例子说明了它是如何工作的。

<?php

// get the test code as string
$testcode = '<?php new '; // will cause a syntax error

// put it in a temporary file
$testfile = tmpfile();
file_put_contents($testfile, $testcode);

exec("php $tempfile", $output, $return_value);

// now you can process the scripts return value and output
// in case of an syntax error the return value is 255
switch($return_value) {
    case 0 :
        echo 'PASSED';
        break;
    default :
        echo 'FAILED ' . $output;

}

// clean up
unlink($testfile);