I am using PHPUnit for my unit tests I am using a mock object to test if a method is called with the correct parameters. This works fine when I just want to do this once.
$logMock = $this->getMockBuilder('Logger')
->disableOriginalConstructor()
->getMock();
//check if it updates the correct record
$logMock->expects($this->exactly(1))
->method('updateLog')
->with(456, 'some status');
Now I have the situation that I want to test if the updateLog is called a second time (with different parameters). I don't see how I can do this with the 'with' method.
Does anybody have a suggestion?
I don't know your mocking framework. Usually you just create another expectation though. I assume that should work with this framework as well.
$logMock->expects($this->exactly(1))
->method('updateLog')
->with(100, 'something else');
Edit
It seems that the PHPUnit framework doesn't support multiple different expectations on the same method. According to this site you have to use the index functionality.
It would then look like this
$logMock->expects($this->at(0))
->method('updateLog')
->with(456, 'some status');
$logMock->expects($this->at(1))
->method('updateLog')
->with(100, 'something else');
$logMock->expects($this->exactly(2))
->method('updateLog');
returnCallback
If you can't use withConsecutive()
, possibly because you are on an old version of PHPUnit, you have another option with returnCallback
.
The returnCallback
function is invoked each time your mock method is invoked. This means you can save the arguments that are passed to it for later inspection. For instance:
$actualArgs = array();
$mockDependency->expects($this->any())
->method('setOption')
->will($this->returnCallback(
function($option, $value) use (&$actualArgs){
$actualArgs[] = array($option, $value);
}
));
$serviceUnderTest->executeMethodUnderTest();
$this->assertEquals(
array(
array('first arg of first call', 'second arg of first call'),
array('first arg of second call', 'second arg of second call'),
),
$actualArgs);
As of PHPUnit 4.2, you can use the withConsecutive
assertion. Provided that you know the order of the calls. Your mock would look like this:
$logMock->expects($this->exactly(2))
->method('updateLog')
->withConsecutive(
array(456, 'some status')
array(100, 'something else')
);
The previous answer is correct.
you can find the answer in the PHPUnit manual http://www.phpunit.de/manual/3.6/en/phpunit-book.html#test-doubles.mock-objects.tables.matchers search for matchers. Matchers are the classes returned by the functions any(), never() etc... The one you need is the PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex, returned by the method at()
you can find more by browsing PHPUnit classes (add to the project path and use an IDE like netbeans to jump to them and see what you can use)
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