Jonathan Petitcolas
Jonathan Petitcolas

Reputation: 4584

Guzzle: mocking external calls in functional tests?

I am currently working on a Symfony3 project using Guzzle. My project calls several externals API, and I would like to mock these requests in my functional tests.

Looking at Guzzle documentation, it seems the way to follow is to use both mock handler and history middleware. Yet, I am surprised there is no built-in solution for this common task (or at least, I didn't find it).

What I would expect is to write my tests with something like:

$mockedClient = new MockedClient([
    ['GET', '/foo', 200, 'Hello world!'],
    ['GET', '/bar', 200, 'Hello another world!'],
]);

$mockedClient->verify();

Which solution are you using ? :)

Upvotes: 1

Views: 1926

Answers (2)

Alexey Shokov
Alexey Shokov

Reputation: 5010

Also, take a look at PHPUnit HTTP mock project. It suits perfectly for real acceptance tests, where you want to test your app almoust untouched (without code modification, just small config changes maybe). Internally it's possible by creating a small standalone HTTP server and mock/check all requests inside it.

Upvotes: 1

Pimpreneil
Pimpreneil

Reputation: 61

It is indeed quite tricky as there is no proper Symfony Guzzle wrapper

Here is how I use Guzzle mocking feature in its latest version (it has changed in the latest Guzzle version, it used to be simpler!!):

First of all, I design my service to have the Guzzle client injected (through a second service that extends GuzzleHttp\Client):

my_guzzleclient:
   class: ...MyGuzzleClient
my_service:
   class: ...MyService
   arguments: ['@my_guzzleclient']

Then, in my test, I create a mock handler:

$mock = new MockHandler([
    new Response(200, array(), array())
]);

And finally, I override my custom guzzle client (my_guzzleclient) with a new one that takes my mock handler into account

$client->getContainer()->set('my_guzzleclient', new MyGuzzleClient($mock));

Here is the code of MyGuzzleClient

use GuzzleHttp\Client as BaseClient

class MyGuzzleClient extends BaseClient
{
    /**
     * MyGuzzleClient  constructor.
     * @param bool|MockHandler $handler
     */
    public function __construct($handler = false)
    {
        $options = array();

        if ($handler !== false) {
            $options['handler'] = $handler;
        }

        parent::__construct($options);
    }

Good luck, Arnaud

Upvotes: 1

Related Questions