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

2022-08-30 10:30:09

我想用不同的预期参数调用我的模拟方法两次。这不起作用,因为第二次调用将失败。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() 来匹配第二个调用呢?


答案 1

您需要使用: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()


答案 2

引用类似问题的答案

从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 参数是指给定模拟对象的所有方法调用中从零开始的索引。使用此匹配器时要小心,因为它可能导致与特定实现细节密切相关的脆性测试。


推荐