不理解 php 或狂饮中的嘲笑。

Not understanding mocking in php or in guzzel.

在此寻求帮助。考虑以下 class:

class Details {

    public function details($href) {
        $client = new Client();

        $response = $client->request('GET', $href);
        EveLogHandler::requestLog($response, 'eveonline_item_details.log');

        if ($response->getStatusCode() === 200) {
            return json_decode($response->getBody()->getContents());
        }

        return false;
    }
}

非常基本,我们创建一个客户端,向 href 发送一个 GET 请求,记录响应,然后对状态代码 200 或 return false 进行操作。

我没有得到以下内容:

  1. 如何在不点击 API 的情况下进行测试?
  2. 如何在 class 方法
  3. 中模拟客户端 objects,如 here 所示
  4. 如果这是一个游泳池呢?你会如何模拟游泳池?请参阅下面的示例:

在这个 Pool 示例中,我在另一个 class 中有一个使用池概念的方法:

public function fetchGroupsInfromation(array $groups) {
    $groupInformationContainer = [];

    $createdRequests           = [];
    $acceptedResponses         = [];
    $rejectedResponses         = [];

    $client                    = new Client();

    foreach($groups as $group) {
        array_push($createdRequests, new Request('GET', $group->types->href));
    }

    $pool = new Pool($client, $createdRequests, [
        'concurrency' => 10,
        'fulfilled'   => function ($response, $index) use (&$acceptedResponses) {
            EveLogHandler::requestLog($response, 'eve_online_group_items_responses.log');

            $groupPagesItterator = new GroupPagesItterator(json_decode($response->getBody()->getContents()));
            $acceptedResponses[$index] = iterator_to_array($groupPagesItterator->getAllPages());
        },
        'rejected'    => function ($reason, $index) use(&$rejectedResponses)  {
            array_push($rejectedResponses, $reason);
        },
    ]);

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

我删除了这个方法中的一些其他逻辑,因为我需要帮助的主要事情是了解如何为 class 方法编写测试,这些方法使用第三方服务。

目标是永远不要达到 API,我有几个控制器测试进一步为我做(集成测试,如果你愿意的话)我如何需要测试这样的代码以确保我得到了我所期望的。但我觉得如果我模拟方法或方法中的代码,那时候我只是 "spell checking" 并且我真的需要确保当我传递给你这个时没问题,我 ned x back 或者我需要 y返回。

所以你们能帮我买吗?也许给我一些例子,也许一些链接到关于如何测试这种类型的代码的例子?一些现实世界的东西?

如果使用 Mockery 库,您可以像这样创建一个模拟:

$response = new Response(); // Create an expected response to return.
$mock = \Mockery::mock('Client[request]');
$mock->shouldReceive('request')->withArgs(['GET', $your_href])->andReturn($reponse);

当实际替换代码中的 Client 实例时,技巧就出现了。 new Client() 将始终创建 Client class 的实例,您的模拟对象将永远不会被使用。你有几个选择,其中一个你可以通过 Client 来使用。

function fetchGroupsInformation(array $groups, $client = null) {
    $client = $client ?: new Client();
    ....
}

fetchGroupsInformation($groups, $mock);

一些框架也有在测试期间注入这种东西的方法。问题是你不想在你正在测试的方法中模拟代码,你想在依赖中模拟 运行 的代码。用类似这样的东西替换 Client 的实例允许您编写代码 认为 它调用了这个第三方库并获得了 return 值。然后它处理 return 值。这允许你说 "as long the third-party code works my code does what I expect." 它也阻止了实际进行的调用。您应该测试既模拟有效响应又模拟有效响应的用例。例如,如果您模拟状态为 404 的响应,您的代码是否会按预期响应。

如果您没有编写 Pool 之类的东西,而是从第三方库中使用它,您或多或少会受到他们的摆布。检查他们是否进行了自己的测试。引入不稳定的代码只会让你做更多的工作。