Hi @tzurbaev , what I recently did is create a trait that I attached to any Test Class and then at the beginning of each method that would call on the remote API I'd specifically overrule the responses. The below code was used for that, please note this requires you to add the Guzzle client to IoC (hence the extend call):
<?php
namespace Testing\Mocks;
use GuzzleHttp\Client;
use GuzzleHttp\Message\Response;
use GuzzleHttp\Stream\Stream;
use GuzzleHttp\Subscriber\History;
use GuzzleHttp\Subscriber\Mock;
trait GuzzleMocked
{
protected $guzzleHistory;
protected function mockNextGuzzleRequest(Response $response)
{
$this->mockNextGuzzleRequests([$response]);
}
protected function mockNextGuzzleRequests(array $responses)
{
foreach ($responses as $response) {
if (!($response instanceof Response)) {
throw new \RuntimeException("Response type incorrect.");
}
}
$client = new Client;
$mock = new Mock($responses);
$client->getEmitter()->attach($mock);
$this->guzzleHistory = new History();
$client->getEmitter()->attach($this->guzzleHistory);
$this->app->extend(Client::class, function () use ($client) {
return $client;
});
}
}
This logic uses a mock subscriber, which attaches to the Guzzle client.
We implement a history middleware that tells Guzzle we expect certain responses. The responses can be anything as long as you
use the GuzzleHttp\Message\Response object.
The following local API call would trigger a remote API, which I mocked with a simple status 200 response:
public function testFullStore()
{
$this->mockNextGuzzleRequest(
new Response(200)
);
$this->uri = 'account';
$this->method = "POST";
$this->parameters = array(
'name' => 'Donald Duck',
// .. more
);
$this->callResource();
$this->assertResponseOk();
// .. more asserts
}
Hope this helps.