【问题标题】:CakePHP 3 - Mock HTTP\Client() in integration testCakePHP 3 - 在集成测试中模拟 HTTP\Client()
【发布时间】:2020-01-12 15:32:11
【问题描述】:

我正在使用Cake\Http\Client (book) 访问一些外部应用程序。在我的单元测试中,我实际上无法使用这些服务。

那么如何在控制器集成测试中模拟 Http Client?例如,如果我可以规定确切的响应,而不需要它发出实际的 HTTP 请求,那就太好了。

在我的情况下,请求是在控制器操作中发出的,目标是同一服务器上的其他应用程序。但是,我觉得这个问题的解决方案应该独立于 HTTP 目标。

【问题讨论】:

  • 类似问题但没有给出确切答案:stackoverflow.com/questions/39323548/…
  • 这实际上取决于您的应用程序在何处以及如何准确地发出请求。
  • 我在我的问题中添加了一些细节。它来自控制器和应用程序外部但在同一服务器上的 url。

标签: unit-testing cakephp request cakephp-3.0


【解决方案1】:

考虑到我在文档或 api 页面中找不到任何内容,我很确定没有内置的解决方案来模拟 Http\Client 对象。

所以我改用另一个 PHP HTTP 客户端,Guzzle。 Guzzle 确实允许通过排队预定义的响应来模拟,这正是我想要的。

然而,与 CakePHP 的平滑集成并非易事,因为 Guzzle 客户端构造函数需要传递模拟堆栈。我通过创建客户端工厂解决了这个问题:

<?php

namespace App\Guzzle;

use GuzzleHttp\Client;

/**
 * Guzzle factory
 * 
 * Created to make guzzle clients mockable
 */
class GuzzleFactory
{
    static $options = [];

    /**
     * Create new client
     * 
     * @return \GuzzleHttp\Client
     */
    static function create()
    {
        return new Client(self::$options);
    }

    /**
     * Set handler stack in global options for new clients
     * 
     * @param \GuzzleHttp\HandlerStack $handlerStack
     */
    static function setTest($handlerStack)
    {
        self::$options['handler'] = $handlerStack;
    }

    /**
     * Set options array to default
     */
    static function reset()
    {
        self::$options = [];
    }
}

然后在我的控制器测试中我有这个功能:

/**
 * Set Guzzle mock responses
 * 
 * @param array $list
 */
public function setGuzzleResponses($list)
{
    if (!is_array($list))
    {
        $list = [$list];
    }
    $mock = new MockHandler($list);
    $handlerStack = HandlerStack::create($mock);
    GuzzleFactory::setTest($handlerStack);
}

这样我就可以在测试中调用:

    // ...
    $this->setGuzzleResponses([
        new Response(200, [], json_encode($response))
    ]);
    $this->get("/page/index"); // This request will make an HTTP call
    // ...

另见http://docs.guzzlephp.org/en/stable/testing.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-12
    • 2018-03-10
    • 2016-08-19
    • 2012-04-25
    • 1970-01-01
    • 2019-08-19
    • 1970-01-01
    • 2019-12-07
    相关资源
    最近更新 更多