Testen van Guzzle-clients

Guzzle biedt verschillende hulpmiddelen waarmee je gemakkelijk de HTTP laag kunt bespotten zonder dat je verzoeken over het internet hoeft te sturen.

  • Mock handler
  • Geschiedenis middleware
  • Node.js webserver voor integratietesten

Mock-handler

Bij het testen van HTTP clients, moet je vaak specifieke scenario's simuleren zoals het retourneren van een succesvol antwoord, het retourneren van een fout, of het retourneren van specifieke antwoorden in een bepaalde volgorde. Omdat unit tests voorspelbaar moeten zijn, makkelijk en snel op te starten, is het gebruiken van een echte remote API een test geur.

Guzzle voorziet in een mock handler die gebruikt kan worden om HTTP verzoeken te vervullen met een antwoord of uitzondering door retourwaarden uit een wachtrij te verschuiven.

use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Exception\RequestException;

// Create a mock and queue two responses.
$mock = new MockHandler([
    new Response(200, ['X-Foo' => 'Bar'], 'Hello, World'),
    new Response(202, ['Content-Length' => 0]),
    new RequestException('Error Communicating with Server', new Request('GET', 'test'))
]);

$handlerStack = HandlerStack::create($mock);
$client = new Client(['handler' => $handlerStack]);

// The first request is intercepted with the first response.
$response = $client->request('GET', '/');
echo $response->getStatusCode();
//> 200
echo $response->getBody();
//> Hello, World
// The second request is intercepted with the second response.
echo $client->request('GET', '/')->getStatusCode();
//> 202

// Reset the queue and queue up a new response
$mock->reset();
$mock->append(new Response(201));

// As the mock was reset, the new response is the 201 CREATED,
// instead of the previously queued RequestException
echo $client->request('GET', '/')->getStatusCode();
//> 201

Wanneer er geen antwoorden meer in de wachtrij staan en een verzoek wordt verzonden, wordt er een OutOfBoundsException geworpen.

Geschiedenis Middleware

Wanneer je dingen gebruikt zoals de Mock handler, moet je vaak weten of de requests die je verwachtte te versturen precies zo verstuurd werden als je bedoelde. Terwijl de mock handler antwoordt met gemodelleerde antwoorden, onderhoudt de history middleware een geschiedenis van de verzoeken die door een cliënt werden verzonden.

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;

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

$handlerStack = HandlerStack::create();
// or $handlerStack = HandlerStack::create($mock); if using the Mock handler.

// Add the history middleware to the handler stack.
$handlerStack->push($history);

$client = new Client(['handler' => $handlerStack]);

$client->request('GET', 'http://httpbin.org/get');
$client->request('HEAD', 'http://httpbin.org/get');

// Count the number of transactions
echo count($container);
//> 2

// Iterate over the requests and responses
foreach ($container as $transaction) {
    echo $transaction['request']->getMethod();
    //> GET, HEAD
    if ($transaction['response']) {
        echo $transaction['response']->getStatusCode();
        //> 200, 200
    } elseif ($transaction['error']) {
        echo $transaction['error'];
        //> exception
    }
    var_dump($transaction['options']);
    //> dumps the request options of the sent request.
}

Test Web Server

Het gebruik van mock responses is bijna altijd voldoende bij het testen van een web service client. Wanneer je aangepaste HTTP handlers implementeert, zal je HTTP requests moeten sturen om de handler voldoende te kunnen testen. Het is echter het beste om contact te maken met een lokale webserver in plaats van een server over het internet.

  • Tests zijn betrouwbaarder
  • Tests vereisen geen netwerkverbinding
  • Tests hebben geen externe afhankelijkheden

De testserver gebruiken

Waarschuwing

De volgende functionaliteit wordt aangeboden om ontwikkelaars van Guzzle te helpen HTTP handlers te ontwikkelen. Er is geen belofte van achterwaartse compatibiliteit als het gaat om de node.js testserver of de GuzzleHttpTestserver klasse. Als je de testserver of Server klasse gebruikt buiten guzzlehttp/guzzle, dan zal je autoloading moeten configureren en ervoor zorgen dat de webserver handmatig wordt gestart.

Hint

U hoeft deze test webserver bijna nooit te gebruiken. Je zou alleen ooit moeten overwegen om hem te gebruiken bij het ontwikkelen van HTTP handlers. De test webserver is niet nodig voor het spotten van verzoeken. Gebruik daarvoor de Mock handler en geschiedenis middleware.

Guzzle wordt geleverd met een node.js testserver die verzoeken ontvangt en antwoorden antwoorden retourneert vanuit een wachtrij. De testserver stelt een eenvoudige API ter beschikking die wordt gebruikt om antwoorden te enqueue-en en de ontvangen verzoeken te inspecteren.

Elke operatie op het Server object zal ervoor zorgen dat dat de server draait en wacht tot hij in staat is om aanvragen te ontvangen alvorens terug te keren.

GuzzleHttpTestserver voorziet in een statische interface naar de testserver. Je kunt een HTTP antwoord of een array van antwoorden in een wachtrij plaatsen door Server::enqueue() aan te roepen. Deze methode aanvaardt een array van PsrttpMessageResponseInterface en Exception objecten.

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Tests\Server;

// Start the server and queue a response
Server::enqueue([
    new Response(200, ['Content-Length' => 0])
]);

$client = new Client(['base_uri' => Server::$url]);
echo $client->request('GET', '/foo')->getStatusCode();
// 200

Wanneer een antwoord op de testserver in de wachtrij wordt geplaatst, verwijdert de testserver alle eerder in de wachtrij geplaatste reacties. Wanneer de server aanvragen ontvangt, worden antwoorden in de wachtrij uit de wachtrij verwijderd en naar de aanvraag teruggestuurd. Wanneer de wachtrij leeg is, stuurt de server een 500-antwoord terug.

Je kan de aanvragen die de server heeft opgehaald bekijken door Server::received() op te roepen.

foreach (Server::received() as $response) {
    echo $response->getStatusCode();
}

Je kan de lijst van ontvangen aanvragen van de webserver leegmaken met de Server::flush() methode.

Server::flush();
echo count(Server::received());
// 0