Guzzle提供了几个工具,可以让你轻松模拟HTTP层,而不需要通过互联网发送请求。
在测试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\ResponseInterface
和 Exception
对象。
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