我正在编写一个 PHPUnit 测试,我需要模拟一些依赖项,但我需要一些方法才能使其仍然像以前一样工作。即,我有:
class Dependency {
// some stuff not important for the test
public function thisOneINeed() {
/// complex code
}
// some more stuff
}
所以我正在做这样的事情:
// prepare mock object
$dep = $this->getMockBuilder('Dependency')->disableOriginalConstructor()->getMock();
// mock out some other method that should return fixed value
$dep->expects($this->any())->method("shouldGetTrue")->will($this->returnValue(true));
// run test code, it will use thisOneINeed() and shouldGetTrue()
$result = $testSubject->runSomeCode($dep);
$this->assertEquals($expected, $result);
除了方法之外一切都很好thisOneINeed()
被模拟出来了,所以我没有运行复杂的代码,我需要它运行runSomeCode()
才能正常工作。该代码在thisOneINeed()
不调用任何其他方法,但正确的测试需要它,并且它不返回固定值,因此我不能只将 static returnValue() 放在那里。并且 AFAIK PHPunit 没有类似的方法returnValue()
上面写着“打电话给家长”。它有returnCallback()
但据我所知,没有办法告诉它“为父类调用此方法”。
我可以列出所有方法Dependency
, 消除thisOneINeed
从它并将其传递给setMethods()
在构建模拟时,但我不喜欢这种方法,看起来很笨拙。
我也可以这样做:
class MockDependency extends Dependency
{
// do not let the mock kill thisOneINeed function
final public function thisOneINeed()
{
return parent::thisOneINeed();
}
}
然后使用MockDependency
构建模拟对象,这也有效,但我不喜欢手动进行模拟。
那么有没有更好的方法来做到这一点呢?
我认为如果您想使用 PHPUnit 的模拟构建器,那么创建一个包含所有方法的数组,删除您需要的方法,然后将其传递给 setMethods 正是您需要做的。
我个人发现在很多情况下拥有 ReflectionClass 的子类很有用,我可以在需要时向其中添加方法。
class MyReflectionClass extends ReflectionClass
{
public function getAllMethodNamesExcept(array $excluded)
{
$methods = array_diff(
get_class_methods($this->name),
$excluded
);
return $methods;
}
}
您还可以使用不同的模拟框架来支持您想做的事情。例如,Phake https://github.com/mlively/Phake has a 然后调用父级 http://phake.digitalsandwich.com/docs/html/ch04s02.html方法。我最近开始使用 Phake,因为我需要能够捕获传递给方法的参数。它有详细的文档记录,值得一试。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)