Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPUnit and mock request from Guzzle

I have a class with the following function :

public function get(string $uri) : stdClass
{
    $this->client = new Client;
    $response = $this->client->request(
        'GET',
        $uri,
        $this->headers
    );

    return json_decode($response->getBody());
}

How can I mock the request method from PHPUnit? I tried different ways but it always tries to connect to the uri specified.

I tried with :

    $clientMock = $this->getMockBuilder('GuzzleHttp\Client')
        ->setMethods('request')
        ->getMock();

    $clientMock->expects($this->once())
        ->method('request')
        ->willReturn('{}');

But this didn't work. What can I do? I just need to mock the response to be empty.

Thanks

PD : Client comes from (use GuzzleHttp\Client)

like image 296
themazz Avatar asked Feb 27 '18 16:02

themazz


2 Answers

I think as suggested is better to use http://docs.guzzlephp.org/en/stable/testing.html#mock-handler

as it looks like the most elegant way to do it properly.

Thank you all

like image 72
themazz Avatar answered Sep 21 '22 23:09

themazz


I prefer this way to mock a Client in PHP. In this example I am using Guzzle Client.

Clone the code or install it via composer

$ composer require doppiogancio/mocked-client

And then...

$builder = new HandlerStackBuilder();

// Add a route with a response via callback
$builder->addRoute(
    'GET', '/country/IT', static function (ServerRequestInterface $request): Response {
        return new Response(200, [], '{"id":"+39","code":"IT","name":"Italy"}');
    }
);

// Add a route with a response in a text file
$builder->addRouteWithFile('GET',  '/country/IT/json', __DIR__ . '/fixtures/country.json');

// Add a route with a response in a string
$builder->addRouteWithFile('GET',  '{"id":"+39","code":"IT","name":"Italy"}');

// Add a route mocking directly the response
$builder->addRouteWithResponse('GET', '/admin/dashboard', new Response(401));

$client = new Client(['handler' => $builder->build()]);

Once you have mocked the client you can use it like this:

$response = $client->request('GET', '/country/DE/json');
$body = (string) $response->getBody();
$country = json_decode($body, true);

print_r($country);

// will return
Array
(
    [id] => +49
    [code] => DE
    [name] => Germany
)
like image 20
Fabrizio Gargiulo Avatar answered Sep 22 '22 23:09

Fabrizio Gargiulo