【问题标题】:Mock response and use history middleware at the same time in Guzzle在 Guzzle 中同时模拟响应和使用历史中间件
【发布时间】:2017-06-27 16:45:37
【问题描述】:

有没有办法在 Guzzle 中模拟响应和请求?

我有一个发送一些请求的类,我想测试一下。

在 Guzzle doc 中,我找到了一种如何分别模拟响​​应和请求的方法。但是我怎样才能将它们结合起来呢?

因为,如果使用历史堆栈,会费力地尝试发送真正的请求。 而且签证诗,当我模拟响应处理程序无法测试请求时。

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'));


 }
 //...

}

【问题讨论】:

标签: php unit-testing guzzle6 guzzle


【解决方案1】:

@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]);

【讨论】:

  • 谢谢,这让我省了很多麻烦。
【解决方案2】:

首先,您不要模拟请求。这些请求是您将在生产中使用的真实请求。模拟处理程序实际上是一个堆栈,因此您可以在那里推送多个处理程序:

$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'] 将包含您的预设回复,因此没有什么可断言的。

【讨论】:

  • 我收到一个错误 [ErrorException] 传递给 GuzzleHttp\Handler\MockHandler::__invoke() 的参数 1 必须实现接口 Psr\Http\Message\RequestInterface,给定的闭包实例,在 /vendor/ 中调用guzzlehttp/guzzle/src/HandlerStack.php 在第 199 行并定义
  • 啊,抱歉,忘记了 MockHandler 应该使用工厂来创建堆栈。我已经更新了答案。
猜你喜欢
  • 2019-08-04
  • 2016-01-07
  • 1970-01-01
  • 2021-03-10
  • 2021-04-22
  • 2012-06-20
  • 1970-01-01
  • 2022-01-24
  • 2020-08-12
相关资源
最近更新 更多