Test af Guzzle-klienter

Guzzle indeholder flere værktøjer, der gør det muligt for dig nemt at lave sjov med HTTP-laget uden at skulle sende forespørgsler over internettet.

  • Mock handler
  • Historie middleware
  • Node.js webserver til integrationstest

Mock Handler

Når du tester HTTP-klienter, er du ofte nødt til at simulere specifikke scenarier som f.eks. returnering af et vellykket svar, returnering af en fejl eller returnering af specifikke svar i en bestemt rækkefølge. Da enhedstests skal være forudsigelige, nemme at opstarte og hurtige, er det at ramme et faktisk fjern-API en testlugt.

Guzzle indeholder en mock-handler, der kan bruges til at opfylde HTTP-forespørgsler med et svar eller en undtagelse ved at flytte returværdier fra en kø.

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

Når der ikke er flere svar i køen, og der sendes en forespørgsel, udløses en OutOfBoundsException.

Historisk middleware

Når man bruger ting som Mock handler, har man ofte brug for at vide, om den anmodninger, du forventede at sende, blev sendt præcis som du havde tænkt dig. Mens mock handler svarer med mocked-svar, vedligeholder historik-middlewaren en historik over de anmodninger, der blev sendt af en klient.

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.
}

Testwebserver

Det er næsten altid tilstrækkeligt at bruge mock-svar, når du tester en webtjenesteklient. Når du implementerer brugerdefinerede HTTP-handlers, skal du nødt til at sende faktiske HTTP-forespørgsler for at kunne teste handleren tilstrækkeligt. Det er dog bedst at kontakte en lokal webserver i stedet for en server over internettet.

  • Testene er mere pålidelige
  • Testene kræver ikke en netværksforbindelse
  • Testene har ingen eksterne afhængigheder

Brug af testserveren

Advarsel

Følgende funktionalitet er til rådighed for at hjælpe udviklere af Guzzle at udvikle HTTP-handlere. Der er intet løfte om bagudkompatibilitet når det drejer sig om node.js-testserveren eller GuzzleHttp\Tests\Server klasse. Hvis du bruger testserveren eller Server klassen uden for guzzlehttp/guzzle, så skal du konfigurere autoloading og sikre, at webserveren startes manuelt.

Tip

Du har næsten aldrig brug for at bruge denne testwebserver. Du bør kun overveje at bruge den, når du udvikler HTTP-handlere. Testwebserveren er ikke nødvendig for at lave mocking-anmodninger. Til det skal du bruge Mock-handler og historisk middleware.

Guzzle leveres med en node.js-testserver, der modtager anmodninger og returnerer svar fra en kø. Testserveren udsætter en simpel API, der bruges til at sætte svar i køen og inspicere de anmodninger, den har modtaget.

Enhver operation på Server objektet vil sikre, at serveren kører og venter, indtil den er i stand til at modtage anmodninger, før den vender tilbage.

GuzzleHttp\Tests\Server giver en statisk grænseflade til testserveren. Du kan sætte et HTTP-svar eller et array af svar i kø ved at kalde Server::enqueue(). Denne metode accepterer et array af Psr\Http\Message\ResponseInterface og Exception objekter.

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

Når et svar er sat i kø på testserveren, fjerner testserveren alle svar, der tidligere har stået i kø. Efterhånden som serveren modtager forespørgsler, sættes svarene i kø ud af køen og returneres til anmodningen. Når køen er tom, reagerer serveren et 500-svar tilbage.

Du kan inspicere de anmodninger, som serveren har hentet, ved at kalde Server::received().

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

Du kan slette listen over modtagne anmodninger fra webserveren ved hjælp af Server::flush() metoden.

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