我试图测试是否在公共接口中调用受保护的方法.
<?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();
}
}
Run Code Online (Sandbox Code Playgroud)
我知道它被正确调用,但PHPUnit说它从未调用过.
当我测试另一种方式时,从未调用方法时会发生同样的情况:
<?php
abstract class AnotherClassAbstract
{
abstract public foo();
public function doAnotherStuff()
{
$this->_loadCache();
}
protected function _loadCache();
{
// implementation is irrelevant
}
}
<?php
class MyTest extends PHPUnit_Framework_TestCase
{
public function testCalled()
{
$mock = $this->getMockForAbstractClass('AnotherClass');
$mock->expects($this->once())
->method('_loadCache');
$mock->doAnotherStuff();
}
}
Run Code Online (Sandbox Code Playgroud)
调用该方法,但PHPUnit说它不是.
我做错了什么?
编辑 我没有用双冒号声明我的方法,它只是表示它是一个公共方法(接口).已更新为完整的类/方法声明.
编辑2 我应该说我在抽象类中测试一些方法实现(编辑代码来反映这一点).由于我无法实例化该类,我该如何测试呢?
我正在考虑创建一个SomeClassSimple扩展SomeClassAbstract并测试这个.这是正确的方法吗?
Ewa*_*odd 10
在我所拥有的PHPUnit版本中,该类PHPUnit_Framework_MockObject_Mock使用PHP get_class_methods来确定被模拟对象的接口. get_class_methods将只挑选公共方法,而不是受保护或私人方法.
这符合xUnit单元测试的精神.考虑PHPUnit文档关于如何使用Mock对象的示例.在那里,SUT是Subject一种受保护的方法notify.但是,正在测试的方法是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();
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,您的testCalled方法不会创建被测系统(SUT)的实例,这将是SomeClass.doStuff在SomeClass 的模拟中的版本没有做任何事情.特别是,它没有打电话_protectedMethod.
| 归档时间: |
|
| 查看次数: |
7879 次 |
| 最近记录: |