Question

FWIW I'm using 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()

Is there any way to "catch" that Fatal Error and report a passed test?

Was it helpful?

Solution

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()

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.

OTHER TIPS

Here's a complete code snippet of Mchl's answer so people don't have to go through the docs...

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.

This means the test code will be executed in a sub process of 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);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top