如何检查模拟对象的方法不是仅使用特定参数调用的?

How to check that method of a mockobject was not called only with a specific parameter?

我有一个 PHPUnit_Framework_MockObject_MockObjectLogger

在单元测试中,我不希望使用特定字符串参数 doNotCallMeWithThisString.

调用 warn 方法

我已经走到这一步了:

public function testThis()
{
    ...

    $logger = $this->getMockLogger();
    $logger->expects($this->exactly(0))->method('warn')->with(
        $this->equalTo('doNotCallMeWithThisString')
    );
    ...
}

然而这失败了,因为 exactly(0) 将对 warn 方法的任何调用标记为错误,即使字符串参数是 somethingEntirelyUnrelated.

我如何告诉模拟对象对 warn 的任何调用都可以,除非使用该特定字符串调用它?

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

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

关于此的一些要点:

  1. 因为您实际上并不关心调用该方法的频率(或者是否调用它)只要不使用错误参数调用它,您需要使用 $this->any() 作为调用计数匹配器。
  2. 每次调用模拟方法时都会调用回调约束。它 必须 return TRUE 才能匹配约束。

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';
              })
         )
 );

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

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