Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Phpunit 如何对受保护的方法进行单元测试?_Phpunit - Fatal编程技术网

Phpunit 如何对受保护的方法进行单元测试?

Phpunit 如何对受保护的方法进行单元测试?,phpunit,Phpunit,有没有办法对类的受保护或私有方法进行单元测试?现在,我公开了很多方法,以便能够测试它们,这破坏了API 编辑:这里实际回答:对于受保护的方法,您可以对测试中的类进行子类化: class Foo { protected function doThings($foo) { //... } } class _Foo extends Foo { public function _doThings($foo) { retu

有没有办法对类的受保护或私有方法进行单元测试?现在,我公开了很多方法,以便能够测试它们,这破坏了API


编辑:这里实际回答:

对于受保护的方法,您可以对测试中的类进行子类化:

class Foo 
{
    protected function doThings($foo) 
    {
        //...
    }
}


class _Foo extends Foo 
{
    public function _doThings($foo) 
    {
        return $this->doThings($foo);
    }
} 
在测试中:

$sut = new _Foo();
$this->assertEquals($expected, $sut->_doThings($stuff));
对于私有方法来说,这有点困难,您可以使用反射API来调用受保护的方法。另外,有一种观点认为私有方法应该只在重构过程中出现,因此应该被调用它们的公共方法所覆盖,但只有当您首先进行测试并且在现实生活中我们有遗留代码要处理时,这种方法才真正起作用

反射api的链接:

此外,此链接在这方面也很有用:


您可以使用ReflectionMethod类后跟invoke方法来访问私有和/或受保护的方法,但要调用该方法,还需要一个在某些情况下不可能的类实例。基于此,一个很好的例子是:

模拟你的班级:

$mockedInstance = $this->getMockBuilder(YourClass::class)
        ->disableOriginalConstructor()    // you may need the constructor on integration tests only
        ->getMock();
让您的方法接受测试:

$reflectedMethod = new \ReflectionMethod(
    YourClass::class,
    'yourMethod'
);

$reflectedMethod->setAccessible(true);
调用您的私有/受保护方法:

$reflectedMethod->invokeArgs(    //use invoke method if you don't have parameters on your method
    $mockedInstance, 
    [$param1, ..., $paramN]
);

PSR-2不接受将两个类放在一个文件中。所以我不确定子类化是不是一个好的选择。感谢您提供的关于反射的提示。完全正确,在同一个“文件”中仅用于演示目的…事实上,使用PHP7对于匿名类是一个很好的用途。。。