测试Guzzle客户端

Guzzle提供了几个工具,可以让你轻松模拟HTTP层,而不需要通过互联网发送请求。

  • 模拟处理程序
  • 历史中间件
  • 用于集成测试的Node.js网络服务器

模拟处理程序

在测试HTTP客户端时,你经常需要模拟特定的场景,如 返回一个成功的响应,返回一个错误,或以一定的顺序返回特定的 响应。因为单元测试需要是可预测的,易于 因为单元测试需要是可预测的,容易启动的,并且是快速的,因此,击中一个实际的远程API是一种测试气味。

Guzzle提供了一个模拟处理程序,它可以通过将返回值从队列中移出,来完成有响应或异常的HTTP请求。

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

当队列中没有更多的响应并发送请求时,会抛出一个OutOfBoundsException

历史中间件

当使用像 Mock 处理器这样的东西时,你经常需要了解 你期望发送的请求是否完全按照你的意图发送。虽然模拟 处理程序以模拟响应的方式进行响应,而历史中间件则保持着一个 客户端所发送的请求的历史。

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

测试网络服务器

在测试Web服务客户端时,使用模拟响应几乎总是足够的。 当实现自定义HTTP处理程序时,你将需要发送实际的HTTP请求以充分测试处理程序。 你需要发送实际的HTTP请求,以便充分地测试处理程序。 然而,最好的做法是联系本地的网络服务器,而不是通过互联网的服务器。 而不是互联网上的服务器。

  • 测试更可靠
  • 测试不需要网络连接
  • 测试没有外部依赖性

使用测试服务器

警告

以下功能是为了帮助Guzzle的开发人员 开发HTTP处理程序。当涉及到node.js测试服务器或 当涉及到node.js测试服务器或GuzzleHttp\Tests\Server 类。如果你正在使用测试服务器或Server 类之外的 guzzlehttp/guzzle,那么你将需要配置自动加载,并确保手动启动网络服务器。 确保网络服务器是手动启动的。

提示

你几乎不需要使用这个测试网络服务器。你应该只在 考虑在开发HTTP处理程序时使用它。测试网络服务器 不需要用于模拟请求。为此,请使用 模拟处理程序和历史中间件。

Guzzle提供了一个node.js测试服务器,它可以接收请求并从队列中返回 并从队列中返回响应。这个测试服务器提供了一个简单的API,可以用来 它可以用来排队响应并检查它所收到的请求。

服务器对象的任何操作都将确保 服务器正在运行,并在返回之前等待它能够接收请求。 返回。

GuzzleHttp\TestsServer提供了一个测试服务器的静态接口。你可以 你可以通过调用以下命令来排队HTTP响应或响应数组 Server::enqueue() 。这个方法接受一个数组 Psr\Http\Message\ResponseInterfaceException 对象。

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

当一个响应在测试服务器上排队时,测试服务器将删除任何 以前排队的响应。当服务器收到请求时,排队的响应 被取消排队并返回到请求中。当队列为空时,服务器 将返回一个500响应。

你可以通过调用Server::received()来检查服务器所检索到的请求。

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

你可以使用Server::flush()方法清除从Web服务器接收的请求列表。

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