39

Sometimes in my code, I'll check to see if a particular object implements an interface:

if ($instance instanceof Interface) {};

However, creating mocks of said interface in PHPUnit, I can't seem to pass that test.

 // class name is Mock_Interface_431469d7, does not pass above check
 $instance = $this->getMock('Interface'); 

I understand that having a class named Interface is different from a class implementing Interface, but I'm not sure how to get deal with this.

Am I forced to mock a concrete class that implements Interface? Wouldn't that defeat the purpose of using an interface for portability?

Thanks

Bryan M.
  • 17,142
  • 8
  • 46
  • 60

3 Answers3

51

there is also assertInstanceOf as of 3.5.0

Example:

$this->assertInstanceOf('\Models\User', $this->userService->findById(1));
Ben
  • 60,438
  • 111
  • 314
  • 488
Brendon-Van-Heyzen
  • 2,493
  • 2
  • 24
  • 23
  • 3
    _This_ is recommended way of type checking. – Stephane Gosselin May 20 '11 at 09:07
  • 1
    In addition to @stefgosselin answer, this is recommended way of type checking, because you get better, self explaining error messages. Compare ```failed asserting that object is instance of Class``` to ```fail asserting that false is true```. – Mike Doe Feb 10 '15 at 19:51
  • 2
    As of PHP 5.5 you can use `\Models\User::class` instead of `'\Models\User'`, which makes it a lot easier to do refactoring. – Vegard Larsen Jan 09 '17 at 10:08
44

This works for me:

$mock = $this->getMock('TestInterface');
$this->assertTrue($mock instanceof TestInterface);

Maybe it's a typo or maybe $instance isn't what you think it is?

martinvium
  • 556
  • 5
  • 4
  • 12
    Yep, cooler heads prevail. After a night of full sleep, I realized I wasn't using the fully qualified namespace when mocking the object. – Bryan M. Jul 15 '10 at 13:53
  • Slightly different use case, but can I check if an instance is an instance of a class or of a mock of the class. – kapad Aug 24 '13 at 21:51
  • @kapad You see, this is the main point of Polymorphism that you don't have to know if the current object is and instance of class or a mock. If you still need to know, then you do something wrong. P.S. Just FYI you can use [get_class](http://ca1.php.net/manual/en/function.get-class.php) function to know the exact class name of the object – Dmitry Oct 02 '13 at 22:47
  • @dvaffection Already solved using get_class(). I wanted to test, and definitely do something wrong. The point was to check an edge case. – kapad Oct 03 '13 at 23:12
1

Use PhpUnit function assertInstanceOf.

Example:

$this->assertInstanceOf(ResponseInterface::class, $signInResponse);