Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock response and use history middleware at the same time in Guzzle

Is there any way to mock response and request in Guzzle?

I have a class which sends some request and I want to test.

In Guzzle doc I found a way how can I mock response and request separately. But how can I combine them?

Because, If use history stack, guzzle trying to send a real request. And visa verse, when I mock response handler can't test request.

class MyClass {

     public function __construct($guzzleClient) {

        $this->client = $guzzleClient;

    }

    public function registerUser($name, $lang)
    {

           $body = ['name' => $name, 'lang' = $lang, 'state' => 'online'];

           $response = $this->sendRequest('PUT', '/users', ['body' => $body];

           return $response->getStatusCode() == 201;        
    }

   protected function sendRequest($method, $resource, array $options = [])
   {

       try {
           $response = $this->client->request($method, $resource, $options);
       } catch (BadResponseException $e) {
           $response = $e->getResponse();
       }

       $this->response = $response;

      return $response;
  }

}

Test:

class MyClassTest {

  //....
 public function testRegisterUser()

 { 

    $guzzleMock = new \GuzzleHttp\Handler\MockHandler([
        new \GuzzleHttp\Psr7\Response(201, [], 'user created response'),
    ]);

    $guzzleClient = new \GuzzleHttp\Client(['handler' => $guzzleMock]);

    $myClass = new MyClass($guzzleClient);
    /**
    * But how can I check that request contains all fields that I put in the body? Or if I add some extra header?
    */
    $this->assertTrue($myClass->registerUser('John Doe', 'en'));


 }
 //...

}
like image 346
xAoc Avatar asked Feb 09 '17 15:02

xAoc


2 Answers

First of all, you don't mock requests. The requests are the real ones you are going to use in production. The mock handler is actually a stack, so you can push multiple handlers there:

$container = [];
$history = \GuzzleHttp\Middleware::history($container);

$stack = \GuzzleHttp\Handler\MockHandler::createWithMiddleware([
    new \GuzzleHttp\Psr7\Response(201, [], 'user created response'),
]);

$stack->push($history);

$guzzleClient = new \GuzzleHttp\Client(['handler' => $stack]);

After you run your tests, $container will have all transactions for you to assert. In your particular test - a single transaction. You are interested in $container[0]['request'], since $container[0]['response'] will contain your canned response, so there is nothing to assert really.

like image 40
Alex Blex Avatar answered Nov 20 '22 11:11

Alex Blex


@Alex Blex was very close.

Solution:

$container = [];
$history = \GuzzleHttp\Middleware::history($container);

$guzzleMock = new \GuzzleHttp\Handler\MockHandler([
    new \GuzzleHttp\Psr7\Response(201, [], 'user created response'),
]);

$stack = \GuzzleHttp\HandlerStack::create($guzzleMock);

$stack->push($history);

$guzzleClient = new \GuzzleHttp\Client(['handler' => $stack]);
like image 136
xAoc Avatar answered Nov 20 '22 13:11

xAoc