Question

I'm writing a unit test for a REST Service connector which is using a third party tool called Httpful.

Because I do not want to send real requests to the server, I mocked the "send" method from Httpful\Request:

$mockedRequest = $this->getMock('Httpful\Request', array('send'), array(), '', false);
$mockedRequest->expects($this->once())->method('send');

This works fine, but the Request Class has a method called expects itself, which I use in my actual code to define the acceptable mime type of the response.

$this
  ->getRequest('GET')
  ->uri(ENDPOINT . $configurationId) //by default this returns a Request Object (now mocked request)
  ->expects('application/json') //crashes ...
  ->send();

When the code gets executed, I get the following error (which is understandable):

Argument 1 passed to Mock_Request_938fb981::expects() must implement interface PHPUnit_Framework_MockObject_Matcher_Invocation, string given

Is there something like a configurable prefix for methods coming from the Mock Class like "expects"?

Was it helpful?

Solution

I don't think that you will be able to do that using the PHPUnit_MockObject class. But you can code your own and use that instead.

class MockRequest extends \Httpful\Request {

     public $isSendCalled = false;
     public $isUriCalled = false;
     public $isExpectsCalled = false;

     public function uri($url) {
         if($url !== '<expected uri>') {
             throw new PHPUnit_Framework_AssertionFailedError($url . " is not correct");
         }
         $this->isUriCalled = true;
         return $this;
     }

     public function expects($type) {
         if($type !== 'application/json') {
             throw new PHPUnit_Framework_AssertionFailedError($type . " is not correct");
         }
         $this->isExpectsCalled = true;
         return $this;
     }

     public function send() {
          $this->isSendCalled = true;
     }
}

Your line for creating the mock then just becomes:

$mockedRequest = new MockRequest();

If the constructor fo

Then in your test you can verify that the methods are called with

$this->assertTrue($mockedRequest->isSendCalled);
$this->assertTrue($mockedRequest->isUriCalled);
$this->assertTrue($mockedRequest->isExpectsCalled);

This isn't a very dynamic mock but it will pass the type hinting and does your check for you. I would create this mock in the same file as your test (though be careful about not accidentally redefining this class elsewhere in your test suite). But it gets you around the problem of having expects being overridden.

The PHPUnit_Framework_MockObject_MockObject is an interface that sets the signature for expects() also which your class wouldn't meet and so there would be an error if you were able to rename the method.

https://github.com/sebastianbergmann/phpunit-mock-objects/blob/master/src/Framework/MockObject/MockObject.php

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top