53

I've got an interface I'd like to mock. I know I can mock an implementation of that interface, but is there a way to just mock the interface?

<?php
require __DIR__ . '/../vendor/autoload.php';

use My\Http\IClient as IHttpClient;  // The interface
use My\SomethingElse\Client as SomethingElseClient;


class SomethingElseClientTest extends PHPUnit_Framework_TestCase {
  public function testPost() {
    $url = 'some_url';
    $http_client = $this->getMockBuilder('Cpm\Http\IClient');
    $something_else = new SomethingElseClient($http_client, $url);
  }
}

What I get here is:

1) SomethingElseTest::testPost
Argument 1 passed to Cpm\SomethingElse\Client::__construct() must be an instance of
My\Http\IClient, instance of PHPUnit_Framework_MockObject_MockBuilder given, called in
$PATH_TO_PHP_TEST_FILE on line $NUMBER and defined

Interestingly, PHPUnit, mocked interfaces, and instanceof would suggest this might work.

Community
  • 1
  • 1
Dmitry Minkovsky
  • 36,185
  • 26
  • 116
  • 160
  • You have misread that other question, it is using `->getMock()` not `->getMockBuilder()` as you do - and that is as you found out the answer to your problem as well. However IIRC a duplicate of your question here does exist as well but I can't find it right now. – hakre Sep 26 '13 at 13:54
  • Interesting. I couldn't find it in my search. Thanks for the edit. – Dmitry Minkovsky Sep 26 '13 at 17:02
  • you can also accept your answer below so that your question is marked answered. – hakre Sep 26 '13 at 23:28
  • Good call. Doesn't seem like there's more input to be made here. Thank you. – Dmitry Minkovsky Sep 27 '13 at 14:43

3 Answers3

61

Instead of

$http_client = $this->getMockBuilder(Cpm\Http\IClient::class);

use

$http_client = $this->getMock(Cpm\Http\IClient::class);

or

$http_client = $this->getMockBuilder(Cpm\Http\IClient::class)->getMock();

Totally works!

t1gor
  • 1,244
  • 12
  • 25
Dmitry Minkovsky
  • 36,185
  • 26
  • 116
  • 160
  • 9
    I had to $mockBuilder->setMethods(['all','my','interface','methods']) to get it to work. But yeah, works perfectly. Thanks for the help. – Steve Apr 29 '15 at 09:09
  • 2
    only $this->getMockBuilder(...)->getMock() worked for me PHPUnit 7.5.1 – lackovic10 Dec 02 '19 at 18:57
  • `$this->getMock` no long exists since PHPUnit 6 https://stackoverflow.com/a/42762123/1462295 – BurnsBA Mar 30 '22 at 19:45
20

The following works for me:

$myMockObj = $this->createMock(MyInterface::class);
Francesco Borzi
  • 56,083
  • 47
  • 179
  • 252
2
$http_client = $this->getMockBuilder(Cpm\Http\IClient::class)
                    ->setMockClassName('SomeClassName')
                    ->getMock();

The setMockClassName() can be used to fix this in some circumstances.

kervin
  • 11,672
  • 5
  • 42
  • 59