php mock ->expects() 未调用时不会报告错误

问题描述 投票:0回答:2

我有以下模拟对象:

$permutator = $this->getMockBuilder('PermutationClass', 
array('get_permutation'))->disableOriginalConstructor()->getMock();

$permutator->expects($this->at(0))
                  ->method('get_permutation')
                  ->will($this->returnCallback(function($praram1) {
                        return true;
                  }));
$permutator->expects($this->at(1))
                  ->method('get_permutation')
                  ->will($this->returnCallback(function($praram1) {
                        return true;
                  }));

但是,我的经验是,如果由于某种原因“1”处的调用从未被执行,那么就不会报告关于从未满足期望的错误。

如果我添加以下代码:就在预期之前:

$permutator->expects($this->exactly(2))->method('get_permutation');

然后发生的情况是,如果从未调用给定的期望,则会报告错误。然而,这里发生的情况是,由于某种原因,这使得模拟对象的返回值为 NULL,因为我没有设置它。如果我这样设置:

$permutator->expects($this->exactly(2))->method('get_permutation')->will($this->returnValue("THIS SHOULD NEVER BE RETURNED"));

然后,这将成为该函数的所有预期方法调用的返回值。所以 at(0) 和 at(1) 确实被执行(我设置了一些打印语句),但返回值被这个覆盖:

$permutator->expects($this->exactly(2))->method('get_permutation');

我设法使用以下方法获得预期的行为:

$permutator->expects($this->exactly(2))
           ->method('get_permutation')
           ->will( $this->onConsecutiveCalls(
                       $this->returnCallback(function($praram1) {
                           return true;
                       }),
                       $this->returnCallback(function($praram1) {
                           return false;
                       })
                   )
           );

我的意思是,当我明确设定期望时,为什么模拟对象不会抱怨 $this->at(1) 从未被调用?

php unit-testing mocking phpunit
2个回答
0
投票

使用 Mockery,您可以创建

spy
而不是
mock
,然后在测试结束时使用
shouldNotHaveReceived
,这样如果方法被调用,您将收到错误。 像这样的:

$dependency = Mockery::spy(YourDependencyClass::class);
$sut = new SystemUnderTest($dependency);
$sut->execute();
$dependency->shouldNotHaveReceived('method');

-1
投票

这不是

expects
所做的 - 它所做的只是告诉模拟在调用该函数时返回什么。这不是断言。

如果你想断言调用了一个方法,我会查看https://github.com/phpspec/prophecy#spies

或者,您可以使用

returnCallback
保存调用了哪些参数,然后将其与您知道的参数进行比较,例如:

$params = [];
$permutator->expects($this->any())
->method('get_permutation')
->will($this->returnCallback(
    function($param) use (&$params){
        $params[] = $param);
    }
));

doTheThing();

$this->assertEquals(
  array(1,2),
  $params
);
© www.soinside.com 2019 - 2024. All rights reserved.