【问题标题】:How to mock responses for specific URLs with Guzzle?如何使用 Guzzle 模拟特定 URL 的响应?
【发布时间】:2016-01-07 00:47:59
【问题描述】:

Guzzle 6 文档提供了一种模拟 HTTP 调用的简单方法,以便每个请求都返回一个特定的响应:http://docs.guzzlephp.org/en/latest/testing.html#mock-handler

但是,正如文档中所述,MockHandler 定义了一个响应队列,无论 URL 是什么,都将以相同的顺序为每个请求发送响应队列。

如何告诉 Guzzle 在每次调用给定 URL 时发送特定响应?

例如,我想要这个电话:

$client->request('GET', '/products')->getBody();

不提出实际请求,但总是返回:

{'products' => [{id: 1, name: 'Product 1'}, {id: 2, name: 'Product 2'}]

使用 AngularJS $httpBackend 服务很容易:

$httpBackend
    .when('GET', '/products')
    .respond("{id: 1, name: 'Product 1'}, {id: 2, name: 'Product 2'}")

知道如何使用 Guzzle 6 实现这一目标吗?

【问题讨论】:

  • 您能否提供一些有关测试设置或一般应用程序的上下文?我试图理解为什么您需要多次调用任何特定的 url,特别是如果您只是想返回相同的响应。
  • @ShaunBramley 我正在使用 Behat 和 Mink 进行功能测试。所以我在测试中加载了我网站的一个页面(例如Given I am on /catalog),这是一个使用 Guzzle 对外部 API 进行多次调用(例如获取产品的调用和获取最新消息的调用)的页面,我不这样做不必知道调用的顺序。而且我不希望我的测试在我的测试过程中依赖于外部 API(可能会出现故障、缓慢或其他什么),因为这是我要测试的页面(它应该显示来自 API 的产品/新闻),不是 API 本身。这是上下文!
  • 我正在寻找相同的解决方案。我找到了这个库:github.com/eschwartz/GuzzleHttpMock(目前支持guzzle 5,不知道是否支持6个分支)
  • Guzzle 6 的 URL(固定和基于正则表达式)模拟处理程序 - tarampampam/guzzle-url-mock

标签: php unit-testing mocking guzzle guzzle6


【解决方案1】:

使用 guzzle 6,您还可以将函数用作处理程序!并且该函数传递 Request 对象,因此您可以检查 URL 并返回正确的响应。

示例:

        $client = new Client([
            'handler' => function (GuzzleHttp\Psr7\Request $request) {
                $path = $request->getUri()->getPath();

                if ($path === '/url1') {
                    return new GuzzleHttp\Psr7\Response(200, [], '{"body": "Url1"}');
                }

                if ($path === '/url2') {
                    return new GuzzleHttp\Psr7\Response(200, [], '{"body": "Url2"}');
                }
            }
        ]);

        $client->get('/url1');

我希望这对某人有所帮助。

【讨论】:

    【解决方案2】:

    如果您使用 Behat 和 Mink 进行验收测试,最好的选择不是接触应用程序代码本身,而是在应用程序外部模拟(存根)外部资源。例如,如果您想为您的应用模拟 Twitter,最好创建一个单独的 Web 应用(其中包含模拟(存根))并将其 URL 传递给您的应用 (SUT)。

    看看HTTP Mock for PHPUnit:它确实做到了这一点,但目前仅适用于 PHPUnit。 API 与 AngularJS 非常相似:

    $this->http->mock
        ->when()
            ->methodIs('GET')
            ->pathIs('/foo')
        ->then()
            ->body('mocked body')
        ->end();
    $this->http->setUp();
    

    【讨论】:

    • 这很有趣,谢谢!它似乎符合我的要求。我会看看它。
    猜你喜欢
    • 2019-08-04
    • 1970-01-01
    • 2018-04-13
    • 2021-07-17
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 2015-08-21
    • 2018-10-12
    相关资源
    最近更新 更多