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.
}
При тестировании клиента веб-службы почти всегда достаточно использовать имитацию ответов. При реализации пользовательских HTTP-обработчиков, вам потребуется необходимо отправлять реальные HTTP-запросы, чтобы в достаточной степени протестировать обработчик. Однако лучшей практикой является обращение к локальному веб-серверу, а не к серверу через Интернет.
Предупреждение
Следующая функциональность предоставляется для того, чтобы помочь разработчикам Guzzle
разрабатывать HTTP-обработчики. Не обещана обратная совместимость
когда речь идет о тестовом сервере node.js или GuzzleHttp\Tests\Server
класс. Если вы используете тестовый сервер или класс Server
вне класса
guzzlehttp/guzzle, то вам нужно будет настроить автозагрузку и
обеспечить запуск веб-сервера вручную.
Подсказка
Вам практически никогда не понадобится использовать этот тестовый веб-сервер. Вы должны только использовать его при разработке HTTP-обработчиков. Тестовый веб-сервер не нужен для имитации запросов. Для этого, пожалуйста, используйте Mock handler and history middleware.
Guzzle поставляется с тестовым сервером node.js, который принимает запросы и возвращает ответы из очереди. Тестовый сервер предоставляет простой API, который используется для регистрации ответов и проверки полученных запросов.
Любая операция над объектом Server
будет гарантировать, что
сервер запущен и будет ждать, пока он не сможет принимать запросы, прежде чем
возврата.
GuzzleHttp\Tests\Server
предоставляет статический интерфейс к тестовому серверу. Вы
можете поставить в очередь 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()
.
Server::flush();
echo count(Server::received());
// 0