With PHPUnit, I am testing a sequence of method calls using ->at(), like so:
$mock->expects($this->at(0))->method('execute')->will($this->returnValue('foo'));
$mock->expects($this->at(1))->method('execute')->will($this->returnValue('bar'));
$mock->expects($this->at(2))->method('execute')->will($this->returnValue('baz'));
How can I set up the mock so that, in the above scenario, if execute() is called four or more times, it will immediately fail? I tried this:
$mock->expects($this->at(3))->method('execute')->will($this->throwException(new Exception('Called too many times.')));
But this also fails if execute() is not called four times. It needs to fail immediately, otherwise the system under test will produce errors of its own, which causes the resulting error message to be unclear.
I managed to find a solution in the end. I used a comination of $this->returnCallback()
and passing the PHPUnit matcher to keep track of the invocation count. You can then throw a PHPUnit exception so that you get nice output too:
$matcher = $this->any();
$mock
->expects($matcher)
->method('execute')
->will($this->returnCallback(function() use($matcher) {
switch ($matcher->getInvocationCount())
{
case 0: return 'foo';
case 1: return 'bar';
case 2: return 'baz';
}
throw new PHPUnit_Framework_ExpectationFailedException('Called too many times.');
}))
;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With