简体   繁体   English

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

[英]PHP Unit Tests: Is it possible to test for a Fatal Error?

FWIW I'm using SimpleTest 1.1alpha. FWIW我正在使用SimpleTest 1.1alpha。

I have a singleton class, and I want to write a unit test that guarantees that the class is a singleton by attempting to instantiate the class (it has a private constructor). 我有一个单例类,我想编写一个单元测试,通过尝试实例化该类来保证该类是单例(它具有私有构造函数)。

This obviously causes a Fatal Error: 这显然会导致致命错误:

Fatal error: Call to private FrontController::__construct() 致命错误:调用私有FrontController :: __ construct()

Is there any way to "catch" that Fatal Error and report a passed test? 有什么方法可以“捕获”该致命错误并报告通过的测试?

No. Fatal error stops the execution of the script. 不会。致命错误会停止脚本的执行。

And it's not really necessary to test a singleton in that way. 并没有必要以这种方式测试单例。 If you insist on checking if constructor is private, you can use ReflectionClass:getConstructor() 如果您坚持检查构造函数是否为私有,则可以使用ReflectionClass:getConstructor()

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

Another thing to consider is that Singleton classes/objects are an obstacle in TTD since they're difficult to mock. 要考虑的另一件事是,Singleton类/对象在TTD中是一个障碍,因为它们很难模拟。

Here's a complete code snippet of Mchl's answer so people don't have to go through the docs... 这是Mchl答案的完整代码段,因此人们不必阅读文档...

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

You can use a concept like PHPUnit's process-isolation. 您可以使用类似PHPUnit的进程隔离的概念。

This means the test code will be executed in a sub process of php. 这意味着测试代码将在php的子过程中执行。 This example shows how this could work. 此示例显示了它如何工作。

<?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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM