【问题标题】:Testing a class in phpspec involving Guzzle在涉及 Guzzle 的 phpspec 中测试一个类
【发布时间】:2015-06-19 14:32:27
【问题描述】:

我正在尝试构建一个查询外部 API 的类。对应于端点的每个方法都会调用一个“主调用”方法,该方法负责实际向 API 发送请求。

例如:

// $this->http is Guzzlehttp\Client 5.3

public function call($httpMethod, $endpoint, array $parameters = [])
{
    $parameters = array_merge($parameters, [
        'headers' => [
            'something' => 'something'
        ]
    ]);

    $request = $this->http->createRequest($httpMethod, $this->baseUrl . $endpoint, $parameters);

    return $this->http->send($request);
}

public function getAll()
{
    return $this->call('GET', 'all');
}

我应该模拟什么?我应该在 http 客户端的 createRequest()send() 方法上使用 willBeCalled() 和/或 willReturn() 吗?

当我模拟 send() 时,它会说:Argument 1 passed to Double\GuzzleHttp\Client\P2::send() must implement interface GuzzleHttp\Message\RequestInterface, null given 而且我不确定如何为此提供一个假的,因为为该接口创建一个虚拟对象需要我在该类上实现 30 个方法。

这是现在的测试:

function it_lists_all_the_things(HttpClient $http)
{
    $this->call('GET', 'all')->willBeCalled();
    $http->createRequest()->willBeCalled();
    $http->send()->willReturn(['foo' => 'bar']);

    $this->getAll()->shouldHaveKeyWithValue('foo', 'bar'); 
}

【问题讨论】:

    标签: unit-testing guzzle phpspec


    【解决方案1】:

    你应该模拟这种行为,像这样:

    public function let(Client $http)
    {
        $this->beConstructedWith($http, 'http://someurl.com/');
    }
    
    function it_calls_api_correctly(Client $http, Request $request)
    {
        $parameters = array_merge([
            'headers' => [
                'something' => 'something'
            ]
        ]);
    
        $http->createRequest('GET', 'http://someurl.com/all', $parameters)->shouldBeCalled()->willReturn($request);
    
        $http->send($request)->shouldBeCalled();
    
        $this->getAll();
    }
    

    【讨论】:

    • 我想我尝试过类似的方法。问题是,如果我输入提示 GuzzleHttp\Message\RequestInterface $request 并将其传递给 send(),它会说“你需要实现一个 bajillion 方法”。我应该在实现所有这些方法的规范类下面创建一个虚拟类吗?
    • 我尝试了这种方法,但现在我还需要一件事。在我的代码中,我需要返回 $this->http->send($request)->json() 但 phpspec 告诉我它找不到它。目前,我有$http->send($request)->json()->shouldBeCalled()
    • 你需要模拟 send 返回的内容:$this->http->send($request)->shouldBeCalled()->willReturn($whatever)$whatever->json()->shouldBeCalled()
    猜你喜欢
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 2013-05-27
    • 1970-01-01
    相关资源
    最近更新 更多