【发布时间】:2017-06-24 23:45:34
【问题描述】:
有没有办法对类的受保护或私有方法进行单元测试?就像现在一样,我公开了很多方法以便能够测试它们,这破坏了 API。
编辑:实际上在这里回答:Best practices to test protected methods with PHPUnit
【问题讨论】:
标签: phpunit
有没有办法对类的受保护或私有方法进行单元测试?就像现在一样,我公开了很多方法以便能够测试它们,这破坏了 API。
编辑:实际上在这里回答:Best practices to test protected methods with PHPUnit
【问题讨论】:
标签: phpunit
您可以通过使用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]
);
【讨论】:
对于受保护的方法,您可以对被测类进行子类化:
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 的链接:
http://php.net/manual/en/reflectionmethod.setaccessible.php
此外,此链接看起来对此很有用:
【讨论】: