Testing How A Method Is Called, Without Testing Equality

February 14, 2012 by alex

There are times I want to assert that a method is called with a particular kind of argument, but I don’t really care what the exact values of that argument are. PHP’s DateTime is a great example. I want a method to be called with a DateTime, but I don’t care what time it represents, so an equality test doesn’t fit. I just want to know that the calling method is invoking the called method in the right way.

<?php
class Foo {
  public function duff() {
    return $this->fud(new DateTime());
  }
  public function fud(DateTime $date) {
    return $date;
  }
}
?>
<?php
class TestCase extends PHPUnit_Framework_TestCase {
  public function test_duff_calls_fud_with_a_DateTime() {
    $mock = $this->getMock('Foo', array('fud'));
    $mock ->expects($this->once())
      ->method('fud')
      ->with(new PHPUnit_Framework_Constraint_IsInstanceOf('DateTime'));

    $mock->duff();
  }
}
?>

PHPUnit_Framework_Constraint_IsInstanceOf lets me assert that duff() is going to call fud with an instance of DateTime , but I don’t need a reference to that DateTime. This is really useful, and not complex once you see it in action. But it took some digging in the PHPUnit source code to find it.

Hope that’s useful.

☙ ☙ ☙