有没有办法对类的受保护或私有方法进行单元测试?就像现在一样,我公开了很多方法,以便能够测试它们,从而打破了API。
修改:实际上已在此处回答:Best practices to test protected methods with PHPUnit
答案 0 :(得分:3)
您可以先使用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]
);
答案 1 :(得分:0)
对于受保护的方法,您可以对测试中的类进行子类化:
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));
使用私有方法会有点困难,您可以使用Reflection API来调用受保护的方法。此外,有一种观点认为私有方法应该只在重构期间出现,所以应该由调用它们的公共方法覆盖,但只有在测试优先开始时才能真正起作用,并且在现实生活中我们有遗留代码处理;)
反射api的链接:
http://php.net/manual/en/reflectionmethod.setaccessible.php
此外,此链接看起来很有用: