Phpunit: Matching arguments by callback in mock methods calls

Created on 6 Aug 2013  路  5Comments  路  Source: sebastianbergmann/phpunit

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.

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.

All 5 comments

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;
                 }));
Was this page helpful?
0 / 5 - 0 ratings

Related issues

dciancu picture dciancu  路  3Comments

kunjalpopat picture kunjalpopat  路  4Comments

keradus picture keradus  路  3Comments

rentalhost picture rentalhost  路  4Comments

greg0ire picture greg0ire  路  4Comments