Guzzle:在功能测试中模拟外部调用?

Guzzle: mocking external calls in functional tests?

我目前正在使用 Guzzle 开发一个 Symfony3 项目。我的项目调用了几个外部 API,我想在我的功能测试中模拟这些请求。

查看Guzzle documentation,似乎要遵循的方法是同时使用模拟处理程序和历史中间件。然而,令我惊讶的是,对于这个常见任务没有内置的解决方案(或者至少,我没有找到它)。

我希望用类似的东西来编写我的测试:

$mockedClient = new MockedClient([
    ['GET', '/foo', 200, 'Hello world!'],
    ['GET', '/bar', 200, 'Hello another world!'],
]);

$mockedClient->verify();

您使用的是哪种解决方案? :)

这确实很棘手,因为没有合适的 Symfony Guzzle 包装器

以下是我在其最新版本中使用 Guzzle 模拟功能的方式(它在最新的 Guzzle 版本中发生了变化,以前更简单!!):

首先,我将我的服务设计为注入 Guzzle 客户端(通过扩展 GuzzleHttp\Client 的第二个服务):

my_guzzleclient:
   class: ...MyGuzzleClient
my_service:
   class: ...MyService
   arguments: ['@my_guzzleclient']

然后,在我的测试中,我创建了一个模拟处理程序:

$mock = new MockHandler([
    new Response(200, array(), array())
]);

最后,我用一个考虑了我的模拟处理程序的新客户端覆盖了我的自定义 guzzle 客户端 (my_guzzleclient)

$client->getContainer()->set('my_guzzleclient', new MyGuzzleClient($mock));

这是MyGuzzleClient的代码

use GuzzleHttp\Client as BaseClient

class MyGuzzleClient extends BaseClient
{
    /**
     * MyGuzzleClient  constructor.
     * @param bool|MockHandler $handler
     */
    public function __construct($handler = false)
    {
        $options = array();

        if ($handler !== false) {
            $options['handler'] = $handler;
        }

        parent::__construct($options);
    }

祝你好运, 阿诺

另外,看看 PHPUnit HTTP mock 项目。它非常适合真正的验收测试,你想在其中测试你的应用程序几乎不受影响(没有代码修改,可能只是小的配置更改)。在内部,可以通过创建一个小型的独立 HTTP 服务器和 mock/check 它里面的所有请求来实现。