Probando clientes Guzzle

Guzzle proporciona varias herramientas que le permitirán burlarse fácilmente de la capa HTTP sin necesidad de enviar peticiones a través de Internet.

  • Manipulador simulado
  • Historia del middleware
  • Servidor web Node.js para pruebas de integración

Mock Handler

Cuando se prueban clientes HTTP, a menudo es necesario simular escenarios específicos como como la devolución de una respuesta correcta, la devolución de un error, o la devolución de respuestas en un orden determinado. Dado que las pruebas unitarias deben ser predecibles, fáciles de arrancar, y rápido, golpear una API remota real es un olor de prueba.

Guzzle proporciona un manejador de imitación que puede ser utilizado para cumplir con las solicitudes HTTP con una respuesta o una excepción mediante el desplazamiento de los valores de retorno de una cola.

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

Cuando no hay más respuestas en la cola y se envía una solicitud, se lanza una OutOfBoundsException.

Historia Middleware

Cuando se usan cosas como el manejador Mock, a menudo se necesita saber si las solicitudes que esperabas enviar fueron enviadas exactamente como pretendías. Mientras que el mock responde con respuestas simuladas, el middleware del historial mantiene un historia de las peticiones que fueron enviadas por un cliente.

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

Servidor web de prueba

El uso de respuestas simuladas es casi siempre suficiente cuando se prueba un cliente de servicio web. Al implementar handlers HTTP personalizados, necesitarás necesitarás enviar peticiones HTTP reales para poder probar suficientemente el manejador. Sin embargo, la mejor práctica es contactar con un servidor web local en lugar de un servidor a través de Internet.

  • Las pruebas son más fiables
  • Las pruebas no requieren una conexión de red
  • Las pruebas no tienen dependencias externas

Uso del servidor de pruebas

Advertencia

La siguiente funcionalidad se proporciona para ayudar a los desarrolladores de Guzzle a desarrollar manejadores HTTP. No hay ninguna promesa de compatibilidad hacia atrás cuando se trata del servidor de pruebas node.js o de la clase GuzzleHttp\Tests\Server . Si está utilizando el servidor de pruebas o la clase Server fuera de guzzlehttp/guzzle, tendrás que configurar la carga automática y asegurar que el servidor web se inicie manualmente.

Sugerencia

Casi nunca es necesario utilizar este servidor web de prueba. Sólo debería considerar su uso cuando desarrolle manejadores HTTP. El servidor web de prueba no es necesario para realizar peticiones de prueba. Para ello, utilice el Mock handler and history middleware.

Guzzle incluye un servidor de pruebas node.js que recibe peticiones y devuelve respuestas desde una cola. El servidor de pruebas expone una sencilla API que se utiliza para poner en cola las respuestas e inspeccionar las peticiones que ha recibido.

Cualquier operación sobre el objeto Servidor se asegurará de que que el servidor está funcionando y esperará hasta que pueda recibir peticiones antes de regresar.

GuzzleHttp\Tests\Server proporciona una interfaz estática para el servidor de pruebas. Usted puede poner en cola una respuesta HTTP o una matriz de respuestas llamando a Server::enqueue(). Este método acepta una matriz de Psr\Http\Message\ResponseInterface y Exception objetos.

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

Cuando se pone en cola una respuesta en el servidor de pruebas, éste eliminará cualquier respuestas en cola anteriormente. A medida que el servidor recibe solicitudes, las respuestas en cola son retiradas de la cola y devueltas a la solicitud. Cuando la cola está vacía, el servidor devolverá una respuesta 500.

Puede inspeccionar las peticiones que el servidor ha recuperado llamando a Server::received().

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

Puedes borrar la lista de peticiones recibidas del servidor web utilizando el método Server::flush().

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