如何使用PHPUnit测试方法是否为私有

时间:2016-12-21 11:05:52

标签: php phpunit

使用PHPUnit,我想测试一个类不能使用__construct [ new Class(); ]方法实例化,也不能克隆,唤醒等。

基本上它是一个Singleton类,并且__construct__clone__wakeup方法设置为private,以确保它仍然是Singleton。

但我怎么能测试呢?

3 个答案:

答案 0 :(得分:2)

您可以通过尝试从单例实例化新对象来捕获抛出的异常来实现此目的。

尝试以下(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();
    }
}

答案 1 :(得分:1)

按照设计,单元测试通常会检查行为,而不是接口(方法签名是接口的一部分)。

但如果您确实需要,可以使用Reflection API。查看课程hasMethod()和此方法isPrivate()

在PHP7环境中,您可以使用John Joseph提出的try/catch解决方案,但我建议仅拦截Error个例外(Throwable涵盖所有可能的错误,而不仅仅是可见性违规)。此外,PHPUnit有一个@expectedException注释,它比手动try/catch更好。

答案 2 :(得分:0)

所有这些都完美无缺。

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.");
}

非常感谢你。我认为我喜欢的是 expectException 方法。