在PHPUnit中,我如何在连续调用模拟方法时指示不同的with()


In PHPUnit, how do I indicate different with() on successive calls to a mocked method?

我想用不同的预期参数调用我的模拟方法两次。这不起作用,因为expects($this->once())将在第二次调用时失败。

$mock->expects($this->once())
     ->method('foo')
     ->with('someValue');
$mock->expects($this->once())
     ->method('foo')
     ->with('anotherValue');
$mock->foo('someValue');
$mock->foo('anotherValue');

我也试过了:

$mock->expects($this->exactly(2))
     ->method('foo')
     ->with('someValue');

但是我如何添加一个with()来匹配第二个调用?

您需要使用at():

$mock->expects($this->at(0))
     ->method('foo')
     ->with('someValue');
$mock->expects($this->at(1))
     ->method('foo')
     ->with('anotherValue');
$mock->foo('someValue');
$mock->foo('anotherValue');

注意,传递给at()的索引适用于对同一模拟对象的所有方法调用。如果第二个方法调用是bar(),则不会将参数更改为at()

参考类似问题的答案,

从PHPUnit 4.1开始,你可以使用withConsecutive

$mock->expects($this->exactly(2))
     ->method('set')
     ->withConsecutive(
         [$this->equalTo('foo'), $this->greaterThan(0)],
         [$this->equalTo('bar'), $this->greaterThan(0)]
       );

如果你想让它在连续呼叫时返回:

  $mock->method('set')
         ->withConsecutive([$argA1, $argA2], [$argB1], [$argC1, $argC2])
         ->willReturnOnConsecutiveCalls($retValueA, $retValueB, $retValueC);

如果你可以避免使用at(),那么使用它是不理想的,因为正如他们的文档所声明的

at()匹配器的$index参数引用给定模拟对象的所有方法调用中从0开始的索引。使用这个匹配器时要小心,因为它可能导致脆弱的测试,这些测试与特定的实现细节联系得太紧密。

withConsecutive也已弃用。
这篇文章中有一个解决方案:替换PHPUnit方法' withcontinuous '