Guzzle Clients testen

Guzzle bietet mehrere Tools, mit denen Sie die HTTP-Schicht nachahmen können, ohne dass Sie Anfragen über das Internet senden müssen.

  • Mock-Handler
  • Historische Middleware
  • Node.js-Webserver für Integrationstests

Mock-Handler

Beim Testen von HTTP-Clients müssen Sie oft bestimmte Szenarien simulieren, wie Rückgabe einer erfolgreichen Antwort, Rückgabe eines Fehlers oder Rückgabe bestimmter Antworten in einer bestimmten Reihenfolge. Da Unit-Tests vorhersehbar, einfach und schnell sein müssen und schnell sein müssen, ist der Zugriff auf eine tatsächliche Remote-API ein Testgeruch.

Guzzle bietet einen Mock-Handler, der verwendet werden kann, um HTTP-Anfragen mit einer Antwort oder einer Ausnahme zu erfüllen, indem Rückgabewerte aus einer Warteschlange verschoben werden.

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

Wenn keine Antworten mehr in der Warteschlange sind und eine Anfrage gesendet wird, wird eine OutOfBoundsException ausgelöst.

History Middleware

Wenn Sie Dinge wie den Mock Handler verwenden, müssen Sie oft wissen, ob die Anfragen, die Sie zu senden erwarteten, genau so gesendet wurden, wie Sie es beabsichtigten. Während der Mock Handler mit gespielten Antworten antwortet, verwaltet die History-Middleware einen Verlauf der von einem Client gesendeten Anfragen.

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 Webserver

Beim Testen eines Webdienst-Clients ist die Verwendung von Mock Responses fast immer ausreichend. Bei der Implementierung von benutzerdefinierten HTTP-Handlern, müssen Sie müssen Sie tatsächliche HTTP-Anfragen senden, um den Handler ausreichend testen zu können. Am besten ist es jedoch, einen lokalen Webserver zu kontaktieren und nicht einen Server über das Internet.

  • Die Tests sind zuverlässiger
  • Die Tests erfordern keine Netzwerkverbindung
  • Tests haben keine externen Abhängigkeiten

Verwendung des Test-Servers

Warnung

Die folgenden Funktionen sollen Entwicklern von Guzzle helfen HTTP-Handler zu entwickeln. Es gibt kein Versprechen auf Abwärtskompatibilität wenn es um den Node.js Testserver oder die GuzzleHttp\Tests\Server Klasse. Wenn Sie den Testserver oder die Klasse Server außerhalb von guzzlehttp/guzzle verwenden, müssen Sie Autoloading konfigurieren und sicherstellen, dass der Webserver manuell gestartet wird.

Hinweis

Sie brauchen diesen Test-Webserver fast nie zu benutzen. Sie sollten ihn immer nur in Betracht ziehen, wenn Sie HTTP-Handler entwickeln. Der Test-Webserver ist nicht notwendig für Mocking-Anfragen. Dafür verwenden Sie bitte die Mock-Handler und die History-Middleware.

Guzzle wird mit einem node.js-Testserver ausgeliefert, der Anfragen empfängt und Antworten aus einer Warteschlange zurückgibt. Der Testserver stellt eine einfache API zur Verfügung, die verwendet wird, um Antworten in die Warteschlange zu stellen und die erhaltenen Anfragen zu überprüfen.

Jede Operation auf dem Server Objekt wird sicherstellen, dass dass der Server läuft und wartet, bis er in der Lage ist, Anfragen zu empfangen, bevor er zurückkehrt.

GuzzleHttp\Tests\Server bietet eine statische Schnittstelle zum Testserver. Sie können eine HTTP-Antwort oder ein Array von Antworten in eine Warteschlange stellen, indem Sie Server::enqueue(). Diese Methode akzeptiert ein Array von Psr\Http\Message\ResponseInterface und Exception Objekte.

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

Wenn eine Antwort auf dem Testserver in die Warteschlange gestellt wird, entfernt der Testserver alle zuvor in die Warteschlange gestellten Antworten. Wenn der Server Anfragen erhält, werden die in der Warteschlange stehenden Antworten aus der Warteschlange entfernt und an die Anfrage zurückgegeben. Wenn die Warteschlange leer ist, gibt der Server eine 500-Antwort zurück.

Sie können die Anfragen, die der Server abgerufen hat, durch den Aufruf von Server::received() überprüfen.

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

Sie können die Liste der empfangenen Anfragen vom Webserver mit der Methode Server::flush() löschen.

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