Guzzle如何在实际应用程序中测试池

时间:2016-02-03 08:46:05

标签: unit-testing guzzle

看看他们如何测试游泳池的Guzzle测试并没有帮助我,因为他们测试池自己。而且我不想按照说法测试池我想测试我使用它的方式实际上是有效的。

请考虑以下事项:

public function getItemHistoryForRegion(array $items, array $regions) {

    $acceptedResponses = [];

    $this->createRequests($items, $regions);

    $pool = new Pool($this->client, $this->createdRequests, [
        'concurrency' => 18,
        'fulfilled'   => function ($response, $index) use (&$acceptedResponses) {

            $responseJson = json_decode($response->getBody()->getContents());
            $acceptedResponses[$index] = $responseJson;

            $this->populateHistoricalDataContainer($responseJson, $acceptedResponses);
        },
        'rejected'    => function ($reason, $index) use(&$rejectedResponses)  {
            $this->eveLogHandler->messageLog($reason, 'eve_online_region_item_history_rejected_responses.log');
        },
    ]);

    $promise = $pool->promise();
    $promise->wait();

    return end($this->historicalData);
}

我们有一系列基于项目和区域创建的请求。然后,我们创建了一个池对象,并将其转换为我们等待的承诺。

在池的实现部分,我们用一些容器填充容器 回复中提供的信息。

我觉得我可以删除$this->createRequests($items, $regions);部分中的fulfilled和方法调用以及结束返回语句,并将其放在自己的方法中。

然后,我可以测试此方法的所有功能。

但这仍然让我留下了游泳池。我该怎么办?我呢?我的意思是,一旦我删除了所有内容,我就会离开这个:

public function getItemHistoryForRegion() {

    $acceptedResponses = [];

    $pool = new Pool($this->client, $this->createdRequests, [
        'concurrency' => 18,
        'fulfilled'   => function ($response, $index) use (&$acceptedResponses) {
            $responseJson = json_decode($response->getBody()->getContents());
            $acceptedResponses[$index] = $responseJson;
        },
        'rejected'    => function ($reason, $index) use(&$rejectedResponses)  {
            $this->eveLogHandler->messageLog($reason, 'eve_online_region_item_history_rejected_responses.log');
        },
    ]);

    $promise = $pool->promise();
    $promise->wait();

    return $acceptedResponses
}

哪个更好更清洁。但是我该如何测试方法呢?我甚至都不知道从哪里开始。对于那些使用guzzel的人来说,有没有人使用Pool代码库?如果是这样,你如何测试呢?

我唯一想做的就是嘲笑这个方法,但是一旦我嘲笑它,我就没有真正测试它......

我可以为函数创建一个方法包装器然后调用该函数并模拟这个函数并执行一个"我希望这个函数被调用一次并返回一个x"但是,这只是测试函数名称拼写正确并且它被调用。并不是说它获取数据并实际上给我一些东西。

另一个问题我不想让它真正点击任何api服务我只想确保它在运行时获得一系列已接受的响应。我应该做方法包装和嘲笑概念吗?这是偶然的"最佳实践" ??

我在这里不知所措。帮助吗

1 个答案:

答案 0 :(得分:0)

您的第一个代码段并不像它可能那样容易测试。

听起来您可能想要结帐phpspec。我仍然是工作和开发我的规范的新手,但根据你上面列出的代码,我可能想要生成以下方法(开始)。

在执行单元和功能测试时,也应该使用Guzzle MockHandler

class MyClassSpec {
    public function let() {
        // change this method call to suit the constructor of the class under test.
        $this->shouldBeConstructedWith(new Client(['handler'=> new GuzzleHttp\Handler\MockHandler($arrayOfExpectedPsr7ResultObjects)]));

        $items = ['item 1', 'item 2'];
        $regions = ['region1', 'region2'];
    }

    public function it_will_tabulate_historical_data($items, $regions) {

        $this->getItemHistoryForRegion($items, $regions);

        $this->historicalData->shouldBe($ExpectedPostCondition);
    }

    public function it_calculates_requests($items, $regions) {
        // if method returns an array;
        $this->createRequests($items, $regions)->shouldBeLike($arrayOfRequestObjects);

        // if method directly manipulates a class property
        $this->createdRequests->shouldBe($preConditionValue);
        $this->createRequests($items, $regions);
        $this->createdRequests->shouldBe($ExpectedPostConditionValue);
    }
}