如何检查mockobject的方法只是用一个特定的参数调用?

时间:2015-05-13 16:34:10

标签: php unit-testing mocking phpunit

我有一个PHPUnit_Framework_MockObject_MockObject的{​​{1}}。

在单元测试中,我不希望使用特定字符串参数Logger调用warn方法。

我到目前为止:

doNotCallMeWithThisString

然而这失败了,因为public function testThis() { ... $logger = $this->getMockLogger(); $logger->expects($this->exactly(0))->method('warn')->with( $this->equalTo('doNotCallMeWithThisString') ); ... } 标记对exactly(0)方法的任何调用都是错误,即使字符串参数是warn

除非用特定字符串调用,否则如何告诉模拟对象对somethingEntirelyUnrelated的任何调用都没有问题?

2 个答案:

答案 0 :(得分:2)

exactly()方法用于断言模拟方法的调用次数。除非您使用$this->at()作为模拟行为,否则不指定特定调用的参数。 exactly(0)表示通话次数应为0。

将模拟更改为:

 $logger->expects($this->any()) //Or however many times it should be called
        ->method('warn')
        ->with(
              $this->callback(function($argument) {
                  return $argument !== 'doNotCallMeWithThisString';
              })
         )
 );

这使用回调来检查传递给mocked方法的参数,并验证它不等于你的字符串。

The PHPUnit documentation has the constraint types that you can use to verify the arguments of a mock.此时,它没有字符串不等于类型。但是使用回调,你可以制作自己的回调。您的回调只需要检查所使用的参数,如果可以,则返回true,如果不是,则返回false

答案 1 :(得分:1)

您可以使用callback断言。这样,每次调用参数时都会调用您提供的回调方法:

$logger
    ->expects($this->any())
    ->method('warn')
    ->with($this->callback(function($string) {
        return $string !== 'doNotCallMeWithThisString';
    }));

关于这一点的一些要点:

  1. 因为你实际上并不关心多久这个方法(或者如果它被调用的话),只要它没有被调用参数,您需要使用$this->any()作为调用计数匹配器。
  2. 每次调用mocked方法时都会调用回调约束。 必须返回TRUE 才能使约束匹配。