我有一个课程,希望稍后在测试中进行模拟:
class Original {
function calculate($a) { ... }
}
在测试中:
$mock = $this->getMock('Original',['calculate']);
$mock->expcets($this->any())
->will($this->returnValueMap([
[1,'ABC'],
[2,'BCD']
// somehow tell $mock to call the original calculate() here
);
我想告诉$mock
在某些条件下回退到原来的calculate()
,例如,如果参数与任何提供的检查都不匹配。正如我从阅读PhpUnit代码中所理解的那样,如果找不到匹配项,调用者只返回null: - ?
答案 0 :(得分:1)
$mock = $this->getMockBuilder(Original::class)
->setMethodsExcept(['calculate'])->disableOriginalConstructor()
->getMock();
无论如何,这将调用原始的 calculate 函数。
答案 1 :(得分:0)
模拟的要点是不要调用原始文件,因为它具有您无法控制测试的依赖性。当你想要实际测试calculate()函数时,然后调用一个测试并使用带有set参数的普通代码来获得你想要的响应。
class Original {
function calculate($a) { ... }
}
$mock = $this->getMock('Original',['calculate']);
$mock->expcets($this->any())
->will($this->returnValueMap([
[1,'ABC'],
[2,'BCD']
$Orig = new Original();
$this->assertEquals(4, $Orig->calculates('2 * 2');
答案 2 :(得分:0)
您可以通过使用回调来确定返回的值。如果参数与任何固定值都不匹配,请进行真正的调用:
$mock = $this->getMock('Original',['calculate']);
$mock->expects($this->any())
->will($this->returnCallback(function($argument) {
$values = array(
1 => 'ABC',
2 => 'BCD'
);
if (isset($values[$argument]) {
return $values[$argument];
} else {
return (new Original)->calculate($argument);
}
});
作为旁注,需要这可能是测试过于笼统的一种简单。每个测试都应检查您的系统在特定情况下的工作方式。
此致
答案 3 :(得分:0)
您只能指定要模拟的方法。这样,您无需指定的方法就可以遵循原始逻辑:
$myStubObject = $this
->getMockBuilder(Original::class)
->setMethods(["anyButCalculate"])
->getMock();
$myStubObject
->method('calculate')
->withAnyParameters()
->willReturn("expectedResultFromOriginalLogic");