我想使用不同的预期参数调用我的模拟方法两次。这不起作用,因为
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 参数指的是给定模拟对象的所有方法调用中从零开始的索引。使用此匹配器时请务必小心,因为它可能会导致与特定实现细节联系过于紧密的脆弱测试。
as ->at() 和 withConsecutive() 已弃用 我是这样解决的:
如果我们有:
$this->service->foo(
fooFirstParameter: 'firstParamForTheFirstCall',
fooSecondParameter: 'secondParamForTheFirstCall'
);
$this->service->foo(
fooFirstParameter: 'firstParamForTheSecondCall',
fooSecondParameter: 'secondParamForTheSecondCall'
);
然后我们可以模拟并期望参数和返回,如下所示:
$withFirstParameter = ['firstParamForTheFirstCall', 'firstParamForTheSecondCall'];
$withSeoncdParameter = ['secondParamForTheFirstCall', 'secondParamForTheSecondCall'];
$willReturn = ['willReturnInTheFirstCall', 'willReturnInTheSecondCall'];
$mock->expects($this->exactly(2))
->method('foo')
->willReturnCallback(
function (
$fooFirstParameter,
$fooSecondParameter,
) use (
&$withFirstParameter,
&$withSeoncdParameter
&$willReturn,
): string|null {
$this->assertEquals(array_shift($withFirstParameter), $fooFirstParameter);
$this->assertEquals(array_shift($withSeoncdParameter), $fooSecondParameter);
return array_shift($willReturn);
}
);