Reputation: 172
Using PHPUnit, I would like to test that a Class CANNOT be instantiated using the __construct [ new Class(); ]
method as well as cannot be cloned, woken up etc.
Basically it is a Singleton class, and the __construct
, __clone
and __wakeup
methods set to private to make sure it remains a Singleton.
But how can I test for that?
Upvotes: 1
Views: 148
Reputation: 536
All of these are working perfectly.
function testCannotCallConstructor()
{
try {
$log = new Log();
$this->fail('Should never be called!');
} catch (\Throwable $e) {
$this->assertNotEmpty($e->getMessage());
}
//alternative:
$this->expectException(\Error::class);
$log = new Log();
}
public function testConstructPrivate(){
$method = new \ReflectionMethod('\\Core\\Log', '__construct');
$result = $method->isPrivate();
$this->assertTrue( $result, "Log __construct is not private. Singleton not guaranteed.");
}
Thank you very much. I think the one I prefer is the expectException method.
Upvotes: 0
Reputation: 2743
By design, unit test usually checks a behavior, not an interface (method signature is a part of the interface).
But if you really need that you can use the Reflection API. Check the class hasMethod()
and this method isPrivate()
.
In the PHP7 enviroment you can use try/catch
solution proposed by John Joseph, but i recommend to intercept only Error
exceptions (Throwable
covers all possible erros, not only visibility violation). Also PHPUnit has a @expectedException
annotation, it's better than manual try/catch
.
Upvotes: 1
Reputation: 951
You can do this by catching the exception thrown by trying to instantiate a new object from the singleton.
Try the following (PHP 7):
class Single
{
private function __construct() {}
}
class SingleTest extends \PHPUnit_Framework_TestCase
{
function testCannotCallConstructor()
{
try {
$single = new Single();
$this->fail('Should never be called!');
} catch (\Throwable $e) {
$this->assertNotEmpty($e->getMessage());
}
//alternative:
$this->expectException(\Error::class);
$single = new Single();
}
}
Upvotes: 2