在 Guzzle 中同时模拟响应和使用历史中间件
Mock response and use history middleware at the same time in Guzzle
有什么方法可以在 Guzzle 中模拟响应和请求吗?
我有一个 class 发送了一些请求,我想测试一下。
在 Guzzle doc 中,我找到了一种如何分别模拟响应和请求的方法。但是我怎样才能把它们结合起来呢?
因为,如果使用历史堆栈,guzzle 会尝试发送真实请求。
和签证诗句,当我模拟响应处理程序无法测试请求时。
class MyClass {
public function __construct($guzzleClient) {
$this->client = $guzzleClient;
}
public function registerUser($name, $lang)
{
$body = ['name' => $name, 'lang' = $lang, 'state' => 'online'];
$response = $this->sendRequest('PUT', '/users', ['body' => $body];
return $response->getStatusCode() == 201;
}
protected function sendRequest($method, $resource, array $options = [])
{
try {
$response = $this->client->request($method, $resource, $options);
} catch (BadResponseException $e) {
$response = $e->getResponse();
}
$this->response = $response;
return $response;
}
}
测试:
class MyClassTest {
//....
public function testRegisterUser()
{
$guzzleMock = new \GuzzleHttp\Handler\MockHandler([
new \GuzzleHttp\Psr7\Response(201, [], 'user created response'),
]);
$guzzleClient = new \GuzzleHttp\Client(['handler' => $guzzleMock]);
$myClass = new MyClass($guzzleClient);
/**
* But how can I check that request contains all fields that I put in the body? Or if I add some extra header?
*/
$this->assertTrue($myClass->registerUser('John Doe', 'en'));
}
//...
}
首先,您不会模拟请求。这些请求是您将在生产中使用的真实请求。模拟处理程序实际上是一个堆栈,因此您可以将多个处理程序压入其中:
$container = [];
$history = \GuzzleHttp\Middleware::history($container);
$stack = \GuzzleHttp\Handler\MockHandler::createWithMiddleware([
new \GuzzleHttp\Psr7\Response(201, [], 'user created response'),
]);
$stack->push($history);
$guzzleClient = new \GuzzleHttp\Client(['handler' => $stack]);
在您 运行 测试之后,$container
将拥有所有事务供您断言。在您的特定测试中 - 单个事务。您对 $container[0]['request']
感兴趣,因为 $container[0]['response']
将包含您的预设回复,因此实际上没有什么可断言的。
@Alex Blex 非常接近。
解法:
$container = [];
$history = \GuzzleHttp\Middleware::history($container);
$guzzleMock = new \GuzzleHttp\Handler\MockHandler([
new \GuzzleHttp\Psr7\Response(201, [], 'user created response'),
]);
$stack = \GuzzleHttp\HandlerStack::create($guzzleMock);
$stack->push($history);
$guzzleClient = new \GuzzleHttp\Client(['handler' => $stack]);
有什么方法可以在 Guzzle 中模拟响应和请求吗?
我有一个 class 发送了一些请求,我想测试一下。
在 Guzzle doc 中,我找到了一种如何分别模拟响应和请求的方法。但是我怎样才能把它们结合起来呢?
因为,如果使用历史堆栈,guzzle 会尝试发送真实请求。 和签证诗句,当我模拟响应处理程序无法测试请求时。
class MyClass {
public function __construct($guzzleClient) {
$this->client = $guzzleClient;
}
public function registerUser($name, $lang)
{
$body = ['name' => $name, 'lang' = $lang, 'state' => 'online'];
$response = $this->sendRequest('PUT', '/users', ['body' => $body];
return $response->getStatusCode() == 201;
}
protected function sendRequest($method, $resource, array $options = [])
{
try {
$response = $this->client->request($method, $resource, $options);
} catch (BadResponseException $e) {
$response = $e->getResponse();
}
$this->response = $response;
return $response;
}
}
测试:
class MyClassTest {
//....
public function testRegisterUser()
{
$guzzleMock = new \GuzzleHttp\Handler\MockHandler([
new \GuzzleHttp\Psr7\Response(201, [], 'user created response'),
]);
$guzzleClient = new \GuzzleHttp\Client(['handler' => $guzzleMock]);
$myClass = new MyClass($guzzleClient);
/**
* But how can I check that request contains all fields that I put in the body? Or if I add some extra header?
*/
$this->assertTrue($myClass->registerUser('John Doe', 'en'));
}
//...
}
首先,您不会模拟请求。这些请求是您将在生产中使用的真实请求。模拟处理程序实际上是一个堆栈,因此您可以将多个处理程序压入其中:
$container = [];
$history = \GuzzleHttp\Middleware::history($container);
$stack = \GuzzleHttp\Handler\MockHandler::createWithMiddleware([
new \GuzzleHttp\Psr7\Response(201, [], 'user created response'),
]);
$stack->push($history);
$guzzleClient = new \GuzzleHttp\Client(['handler' => $stack]);
在您 运行 测试之后,$container
将拥有所有事务供您断言。在您的特定测试中 - 单个事务。您对 $container[0]['request']
感兴趣,因为 $container[0]['response']
将包含您的预设回复,因此实际上没有什么可断言的。
@Alex Blex 非常接近。
解法:
$container = [];
$history = \GuzzleHttp\Middleware::history($container);
$guzzleMock = new \GuzzleHttp\Handler\MockHandler([
new \GuzzleHttp\Psr7\Response(201, [], 'user created response'),
]);
$stack = \GuzzleHttp\HandlerStack::create($guzzleMock);
$stack->push($history);
$guzzleClient = new \GuzzleHttp\Client(['handler' => $stack]);