I am writing a unit test for a method using PHPUnit. The method I am testing makes a call to the same method on the same object 3 times but with different sets of arguments.
In case someone finds this without looking at the correspondent section in the phpunit documentation, you can use the withConsecutive method
$mock->expects($this->exactly(3))
->method('MyMockedMethod')
->withConsecutive(
[$arg1, $arg2, $arg3....$argNb],
[arg1b, $arg2b, $arg3b....$argNb],
[$arg1c, $arg2c, $arg3c....$argNc]
...
);
The only downside of this being that the code MUST call the MyMockedMethod in the order of arguments supplied. I have not yet found a way around this.
In my case the answer turned out to be quite simple:
$this->expects($this->at(0))
->method('write')
->with(/* first set of params */);
$this->expects($this->at(1))
->method('write')
->with(/* second set of params */);
The key is to use $this->at(n)
, with n
being the Nth call of the method. I couldn't do anything with any of the logicalOr()
variants I tried.
Stubbing a method call to return the value from a map
$map = array(
array('arg1_1', 'arg2_1', 'arg3_1', 'return_1'),
array('arg1_2', 'arg2_2', 'arg3_2', 'return_2'),
array('arg1_3', 'arg2_3', 'arg3_3', 'return_3'),
);
$mock->expects($this->exactly(3))
->method('MyMockedMethod')
->will($this->returnValueMap($map));
Or you can use
$mock->expects($this->exactly(3))
->method('MyMockedMethod')
->will($this->onConsecutiveCalls('return_1', 'return_2', 'return_3'));
if you don't need to specify input arguments
For others who are looking to both match input parameters and provide return values for multiple calls.. this works for me:
$mock->method('myMockedMethod')
->withConsecutive([$argA1, $argA2], [$argB1, $argB2], [$argC1, $argC2])
->willReturnOnConsecutiveCalls($retValue1, $retValue2, $retValue3);