Phpunit 测试是否调用了受保护的方法
我试图测试在公共接口中是否调用了受保护的方法Phpunit 测试是否调用了受保护的方法,phpunit,Phpunit,我试图测试在公共接口中是否调用了受保护的方法 <?php abstract class SomeClassAbstract { abstract public foo(); public function doStuff() { $this->_protectedMethod(); } protected function _protectedMethod(); { // implemen
<?php
abstract class SomeClassAbstract
{
abstract public foo();
public function doStuff()
{
$this->_protectedMethod();
}
protected function _protectedMethod();
{
// implementation is irrelevant
}
}
<?php
class MyTest extends PHPUnit_Framework_TestCase
{
public function testCalled()
{
$mock = $this->getMockForAbstractClass('SomeClass');
$mock->expects($this->once())
->method('_protectedMethod');
$mock->doStuff();
}
}
在我拥有的PHPUnit版本中,类PHPUnit\u Framework\u MockObject\u Mock
使用PHP的get\u class\u方法来确定被模拟对象的接口get\u class\u方法
将仅选择公共方法,而不是受保护或私有方法
这符合xUnit单元测试的精神。考虑PHPUnice文档的如何使用的例子。在那里,SUT是主题
,它有一个受保护的方法通知
。不过,正在测试的方法是doSomething
。考虑到Subject
是一个黑盒子,我们不关心它是如何实现的细节。不过,我们确实关心它的行为。具体来说,我们要求在调用doSomething
时,调用任何附加观察者的update
方法。因此,我们模拟第三方对象Observer
,并设置调用其update
方法的期望。请注意,尽管执行了受保护的方法notify
,但在测试中没有显式命名。这使我们可以随时自由地更改实现,只要行为得到保留
回到你的例子
class MyTest extends PHPUnit_Framework_TestCase
{
public function testCalled()
{
$mock = $this->getMock('SomeClass');
$mock->expects($this->once())
->method('_protectedMethod');
$mock->doStuff();
}
}
在这里,您的testCalled
方法不会创建被测系统(SUT)的实例,这将是SomeClass。SomeClass模拟中的doStuff
版本没有任何作用。特别是,它不调用\u protectedMethod
,看起来您只需要告诉PHPUnit您想要模拟该函数,即:
$mock = $this->getMock('SomeClass',
array('_protectedMethod'));
$mock->expects($this->once())
->method('_protectedMethod');
$mock->doStuff();
谢谢你,伊万,你说得对。当然,如果它是一个模拟对象,它就没有方法的实现。我是多么愚蠢啊。我会认为你的答案是正确的。如果可以的话,请看我的第二次编辑。所以我要测试的是实现,而不是行为,对吗?这对我来说更清楚一点,谢谢。我认为,单元测试比它看起来更像一门艺术。在阅读了GerardMeszaros的《xUnit测试模式:重构测试代码》之后,我更加欣赏它。反过来,这本书是PHPUnit作家塞巴斯蒂安·伯格曼(Sebastian Bergmann)的强烈推荐。
$mock = $this->getMock('SomeClass',
array('_protectedMethod'));
$mock->expects($this->once())
->method('_protectedMethod');
$mock->doStuff();