在特定情况下如何告诉mock调用原始方法?

时间:2013-09-22 13:19:12

标签: php mocking phpunit stub

我有一个课程,希望稍后在测试中进行模拟:

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: - ?

4 个答案:

答案 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");