【问题标题】:Mockery and Guzzle嘲讽和狂饮
【发布时间】:2013-04-20 15:27:45
【问题描述】:

有人用 Mockery 测试 Guzzle 吗?当我尝试为 guzzle 客户端创建模拟时,出现异常:

ErrorException: Runtime Notice: Declaration of Mockery_517a66dfe36b0::__call() should be compatible with Guzzle\Service\Client::__call($method, $args = NULL)

代码如下:

$mock = m::mock('\Guzzle\Service\Client');

谁能帮我解决这个问题?

【问题讨论】:

    标签: php symfony guzzle mockery


    【解决方案1】:

    如果你想创建一个 guzzle 客户端的 mock,为什么不使用 guzzle 提供的 helper:

    $plugin = new Guzzle\Plugin\Mock\MockPlugin();
    $plugin->addResponse(new Guzzle\Http\Message\Response(200));
    $mockedClient = new Guzzle\Http\Client();
    $mockedClient->addSubscriber($plugin);
    
    // The following request will get the mock response from the plugin in FIFO order
    $request = $client->get('http://www.test.com/');
    $request->send();
    
    // The MockPlugin maintains a list of requests that were mocked
    $this->assertContainsOnly($request, $plugin->getReceivedRequests());
    

    来自Unit Testing Guzzle clients

    【讨论】:

    【解决方案2】:

    我找到了解决方法:

    $mock = m::mock('stdClass');
    $mock->shouldReceive('addPerson')->once()->with(m::contains(1,1))->andReturn(array('id' => 1));
    
    $response = new \Guzzle\Http\Message\Response(409);
    $exception = new \Guzzle\Http\Exception\BadResponseException('error message', 409, null);
    $exception->setResponse($response);
    $mock->shouldReceive('addPerson')->once()->with(m::contains(1,2))->andThrow($exception);
    
    $response = new \Guzzle\Http\Message\Response(404);
    $exception = new \Guzzle\Http\Exception\BadResponseException('error message', 404, null);
    $exception->setResponse($response);
    $mock->shouldReceive('addPerson')->once()->with(m::contains(1,3))->andThrow($exception);
    
    $mapper = $this->container->get('ftb.clubs.mapper');
    $mapper->setClient($mock);
    
    $id = $mapper->addPerson(1, 1);
    $this->assertEquals(
        1,
        $id
    );
    

    你觉得这有道理吗?

    【讨论】:

      【解决方案3】:

      即使 Guzzle 自己建议,我更喜欢控制客户端,而不是依赖响应顺序。

      如果我们可以模拟每个请求的响应会怎样?一对一? 这就是我开发这个小型作曲家库的原因。

      $ composer require doppiogancio/mocked-client
      

      借助这个库,您可以使用以下方法模拟特定 url 的响应:

      1. 响应对象
      2. 字符串响应
      3. 文件中包含的响应内容

      只是一个例子

      $builder = new HandlerStackBuilder();
      
      
      // Add a route with a response via callback
      $builder->addRoute(
          'GET', '/country/IT', static function (ServerRequestInterface $request): Response {
              return new Response(200, [], '{"id":"+39","code":"IT","name":"Italy"}');
          }
      );
      
      // Add a route with a response in a text file
      $builder->addRouteWithFile('GET',  '/country/IT/json', __DIR__ . '/fixtures/country.json');
      
      // Add a route with a response in a string
      $builder->addRouteWithFile('GET',  '{"id":"+39","code":"IT","name":"Italy"}');
      
      // Add a route mocking directly the response
      $builder->addRouteWithResponse('GET', '/admin/dashboard', new Response(401));
      
      $client = new Client(['handler' => $builder->build()]);
      

      一旦你模拟了客户端,你可以像这样使用它:

      $response = $client->request('GET', '/country/DE/json');
      $body = (string) $response->getBody();
      $country = json_decode($body, true);
      
      print_r($country);
      
      // will return
      Array
      (
          [id] => +49
          [code] => DE
          [name] => Germany
      )
      

      【讨论】:

        猜你喜欢
        • 2014-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-22
        • 2014-04-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多