Testing Guzzle Clients

Guzzle fornisce diversi strumenti che vi permetteranno di deridere facilmente il livello HTTP senza bisogno di inviare richieste su Internet.

  • Mock handler
  • Storia middleware
  • Node.js web server per i test di integrazione

Mock Handler

Quando si testano i client HTTP, spesso è necessario simulare scenari specifici come restituire una risposta di successo, restituire un errore o restituire specifiche risposte in un certo ordine. Poiché i test unitari devono essere prevedibili, facili facile da avviare e veloce, colpire un'API remota reale è un odore di test.

Guzzle fornisce un mock handler che può essere utilizzato per soddisfare le richieste HTTP con una risposta o un'eccezione spostando i valori di ritorno da una coda.

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

Quando non ci sono più risposte nella coda e viene inviata una richiesta, viene lanciata una OutOfBoundsException.

Storia Middleware

Quando si usano cose come il gestore Mock, spesso è necessario sapere se le richieste che ci si aspettava di inviare sono state inviate esattamente come previsto. Mentre il gestore mock risponde con risposte simulate, il middleware della storia mantiene una storia delle richieste che sono state inviate da un client.

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

Usare risposte finte è quasi sempre sufficiente quando si testa un client di servizi web. Quando si implementa un gestore HTTP, si avrà bisogno di inviare richieste HTTP reali, al fine di testare sufficientemente il gestore. Tuttavia, una buona pratica è quella di contattare un server web locale piuttosto che un server su internet.

  • I test sono più affidabili
  • I test non richiedono una connessione di rete
  • I test non hanno dipendenze esterne

Usando il server di prova

Attenzione

La seguente funzionalità è fornita per aiutare gli sviluppatori di Guzzle a sviluppare gestori HTTP. Non c'è alcuna promessa di compatibilità all'indietro quando si tratta del test server node.js o del GuzzleHttp\Tests\Server classe. Se state usando il test server o la classe Server fuori da guzzlehttp/guzzle, allora dovrete configurare l'autoloading e assicurarsi che il server web sia avviato manualmente.

Suggerimento

Non avete quasi mai bisogno di usare questo server web di prova. Si dovrebbe solo considerare di usarlo solo quando si sviluppano i gestori HTTP. Il server web di test non è necessario per prendere in giro le richieste. Per questo, si prega di utilizzare il Mock handler e il middleware della storia.

Guzzle viene fornito con un server di prova node.js che riceve richieste e restituisce risposte da una coda. Il server di prova espone una semplice API che viene usata per mettere in coda le risposte e ispezionare le richieste che ha ricevuto.

Qualsiasi operazione sull'oggetto Server si assicurerà che il server sia in funzione e aspetterà che sia in grado di ricevere richieste prima di tornare.

GuzzleHttp\Tests\Server fornisce un'interfaccia statica al server di test. Voi potete mettere in coda una risposta HTTP o un array di risposte chiamando Server::enqueue(). Questo metodo accetta un array di Psr\Http\Message\ResponseInterface e Exception oggetti.

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

Quando una risposta viene messa in coda sul server di test, il server di test rimuove qualsiasi risposte precedentemente accodate. Man mano che il server riceve richieste, le risposte accodate vengono rimosse dalla coda e restituite alla richiesta. Quando la coda è vuota, il server restituirà una risposta 500.

Puoi ispezionare le richieste che il server ha recuperato chiamando Server::received().

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

Puoi cancellare la lista delle richieste ricevute dal server web usando il metodo Server::flush().

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