Now there are limited number of methods to match arguments data of called mock methods. For example:
$mock>expects($this->once())
->method('sendMessage')
->with($this->equalTo(123))
But what if we want to match arguments more dynamicaly? What if there is SomeClass object as argument and we want to assert properties of this object?
$mock->expects($this->once())
->method('sendMessage')
->with($this->matchByCallback(function ($value, PHPUnit_Framework_TestCase $test) {
$test->assertInstanceOf('SomeClass', $value);
$test->assertNotEmpty($value->goodness);
return true;
}));
Or without assertion, just:
$mock->expects($this->once())
->method('sendMessage')
->with($this->matchByCallback(function ($value, PHPUnit_Framework_TestCase $test) {
return !empty($value->goodness);
}));
So when callback returns true it means that argument value was matched to expected.
I think it's really very useful and 'll be very grateful if it will be implemented.
Thank you.
Oh, I found that there is already $this->callback() method to match arguments. It's sad that there is nothing about it in Manual.
I had a similar problem, but I found a more straightforward approach. To check an attribute for a value:
$mock->expects($this->once())
->method('sendMessage')
->with($this->attributeEqualTo('goodness', true) );
This doesn't do exactly as the original OP wanted, but may nevertheless be useful, so I thought I'd post it here.
@barbushin could you provide a code example of how $this->callback() is supposed to be used?
Geez, i just accidentally un-upvoted the above comment because it was my year-old comment...
Just one gotcha, if you have multiple arguments and you want to match the second one, the call becomes:
$mock->expects($this->once())
->method("fetchSomething")
->with($this->anything(), $this->callback(function($date) use ($weekAgo) {
return $date->diffInSeconds($weekAgo) < 1;
}));
Most helpful comment
Oh, I found that there is already $this->callback() method to match arguments. It's sad that there is nothing about it in Manual.