FWIW 我正在使用 SimpleTest 1.1alpha。
我有一个单例类,我想编写一个单元测试,通过尝试实例化类来保证该类是单例(它有一个私有构造函数)。
这显然会导致致命错误:
致命错误:调用私有 FrontController::__construct()
有没有办法“捕捉”那个致命错误并报告通过的测试?
FWIW 我正在使用 SimpleTest 1.1alpha。
我有一个单例类,我想编写一个单元测试,通过尝试实例化类来保证该类是单例(它有一个私有构造函数)。
这显然会导致致命错误:
致命错误:调用私有 FrontController::__construct()
有没有办法“捕捉”那个致命错误并报告通过的测试?
不会。致命错误会停止脚本的执行。
而且实际上没有必要以这种方式测试单例。如果你坚持检查构造函数是否是私有的,你可以使用ReflectionClass:getConstructor()
public function testCannotInstantiateExternally()
{
$reflection = new \ReflectionClass('\My\Namespace\MyClassName');
$constructor = $reflection->getConstructor();
$this->assertFalse($constructor->isPublic());
}
要考虑的另一件事是单例类/对象是 TTD 中的一个障碍,因为它们难以模拟。
这是 Mchl 答案的完整代码片段,因此人们不必阅读文档...
public function testCannotInstantiateExternally()
{
$reflection = new \ReflectionClass('\My\Namespace\MyClassName');
$constructor = $reflection->getConstructor();
$this->assertFalse($constructor->isPublic());
}
您可以使用 PHPUnit 的进程隔离之类的概念。
这意味着测试代码将在 php.ini 的子进程中执行。这个例子展示了它是如何工作的。
<?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);