Mocking GuzzlePHP in phpunit

05 Mar 2017 in GuzzlePHP, phpunit

Suppose you have a class making some HTTP calls. Using the GuzzlePHP library instead of curl or file_get_contents has the benefit of using a simple interface for building HTTP requests:

    <?php
    class MyClass
    {
        private $client;
        private $params = [
            "url"     => "http://some-api-endpoint-url",
            "key"     => null,
            "timeout" => 30,
        ];

        public function __construct(GuzzleHttp\Client $client, array $params = [])
        {
            $this->client = $client;
            $this->params = array_merge($this->params, $params);
        }

        public function callTheApi()
        {
            $response = $this->client->post(
                "{$this->params["url"]}?key={$this->params["key"]}",
                [
                    'headers' => [
                        'Content-Type' => 'application/json',
                        'Accept'       => 'application/json'
                    ],
                    'timeout' => $this->params["timeout"],
                ]
            );
            return GuzzleHttp\json_decode(
                $response->getBody()->getContents()
            );
        }
    }

When unit testing a piece of code like this, instead of mocking the GuzzlePHP client via phpunit's mock methods, you can utilize the GuzzleHttp\Handler\MockHandler like below:

    <?php
    class MyClassTest extends PHPUnit_Framework_TestCase
    {
        private $sut; // system under test
        private $client;
        private $handler;

        function setup()
        {
            $this->handler = new GuzzleHttp\Handler\MockHandler();
            $this->client = new GuzzleHttp\Client([
                'handler' => GuzzleHttp\HandlerStack::create($this->handler)
            ]);
            $this->sut = new MyClass($this->client, $params = []);
        }

        function testCallTheApi()
        {
            $this->handler->append(new GuzzleHttp\Psr7\Response(200));
            $result = $this->sut->callTheApi();
            // assertions follow
        }
    }

Head over to http://docs.guzzlephp.org/en/latest/testing.html for the full documentation. And remember, always test your code.