1

我只是在阅读 Zend Framework 2 单元测试教程。在设置单元测试的过程中,他们在方法中插入了一个硬编码路径到应用程序配置setUp

namespace AlbumTest\Controller;

use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;

class AlbumControllerTest extends AbstractHttpControllerTestCase
{
    public function setUp()
    {
        $this->setApplicationConfig(
            include '/var/www/zf2-tutorial/config/application.config.php'
        );
        parent::setUp();
    }
}

我不敢相信这实际上已经完成并用作示例。

问题是,如何在单元测试setUp方法中获取应用程序配置而不对其路径进行硬编码?

更新:

我对此的另一个相关问题是,为什么“模块”的单元测试需要访问应用程序配置?一个模块的“单元测试”不是应该与这个单个模块隔离吗?

更新 2:

在摆弄了一段时间后,我发现了一个相关的问题。在创建 Album 模块的教程中,指出使用 Composer 创建类映射而不是在Module.phpfor方法中返回配置结构。getAutoloaderConfig但是,当您这样做时,您的单元测试将无法工作,因为您缺少部分配置。要解决这部分问题,您需要autoload_classmap.php在模块基目录中创建一个并在其中返回一个空数组。然后使用代码中概述的代码getAutoloaderConfig让您的测试工作。

我仍然没有找到解决硬编码应用程序配置问题的解决方案,以及为什么实际上需要首先访问它。我正在测试一个模块,而不是一个应用程序。

4

3 回答 3

1

我总是使用下面介绍的函数,直接来自http://framework.zend.com/manual/2.3/en/tutorials/unittesting.html

protected static function findParentPath($path)
{
    $dir = __DIR__;
    $previousDir = '.';
    while (!is_dir($dir . '/' . $path)) {
        $dir = dirname($dir);
        if ($previousDir === $dir) {
            return false;
        }
        $previousDir = $dir;
    }
    return $dir . '/' . $path;
}

将该函数放在 ControllerTest 类中,并在setUp函数中使用它,如下所示:

public function setUp()
{
    $modulePath = static::findParentPath("module");
    $this->setApplicationConfig(
        include $modulePath . '/../config/application.config.php'
    );
    parent::setUp();
}
于 2014-12-13T21:16:23.513 回答
1

将应用程序配置路径硬编码到$this->setApplicationConfig()方法中就像Zend 2 Official Doc非常非常糟糕的代码

为了解决这个问题,您可以使用@slawoj的答案,他们使用Bootstrap 类中的findParentPath($path)方法进入同一个 Zend 2 官方文档来获取应用程序配置路径。

还有另一个答案,可能会更好:

在 Zend 2 官方文档中使用 Same Bootstrap 类,并添加一个静态成员保存应用程序配置数组,用于启动服务管理器静态成员。

引导程序.php

class Bootstrap
{
    /**
     * ServiceManger Static member
     * @var ServiceManager
     */
    private static $serviceManager;

    /**
     * Application Configuration static member
     * @var array
     */
    private static $applicationConfiguration;

    /**
     * Initialize Tests Bootstrap
     */
    public static function init()
    {
        static::initAutoloader();
        if (file_exists(static::findParentPath('code') . '/config/application.config.php')) {
            // include application configuration
            $configuration = require static::findParentPath('code') . '/config/application.config.php';
            // initialize application configuration static member
            static::$applicationConfiguration = $configuration;
            // initialize service manager static member
            $serviceManager = new ServiceManager(new ServiceManagerConfig());
            $serviceManager->setService('ApplicationConfig', $configuration);
            $serviceManager->get('ModuleManager')->loadModules();
            static::$serviceManager = $serviceManager;
        }
    }

    /**
     * Get Application Service Manager
     * @return ServiceManager
     */
    public static function getServiceManager()
    {
        return static::$serviceManager;
    }

    /**
     * Get Application Configuration
     * @return array
     */
    public static function getApplicationConfig()
    {
        return static::$applicationConfiguration;
    }

    /**
     * Get Full Path include given path with it's parent path
     * @param string $path path name which we want to get it's parent
     * @return string
     */
    public static function findParentPath($path)
    {
        $dir = __DIR__;
        $previousDir = ".";
        // loop on Directories Path until get parent path
        while (!is_dir($dir . '/' . $path)) {
            $dir = dirname($dir);
            if ($previousDir == $dir) {
                return false;
            }
            $previousDir = $dir;
        }
        return $dir . '/' . $path;
    }

   // ........
}

然后使用应用程序配置静态成员$this->setApplicationConfig()方法。

你的 AlbumControllerTest 类

class AlbumControllerTest extends AbstractHttpControllerTestCase
{
    public function setUp()
    {
        $this->setApplicationConfig(
            Bootstrap::getApplicationConfig()
        );
        parent::setUp();
    }
}

最后的解释可以解决你的第一个问题吗

如何在单元测试设置方法中获取应用程序配置而不对其路径进行硬编码?

在其他人手中:关于你的第二个问题

为什么实际上首先需要访问它。我正在测试一个模块,而不是一个应用程序

正如它向大多数测试用例类推荐的那样,AbstractHttpControllerTestCase就像他们在 Zend 2 官方文档中所说的那样扩展

我们在这里扩展的AbstractHttpControllerTestCase类帮助我们设置应用程序本身,帮助调度和请求期间发生的其他任务,以及提供断言请求参数、响应标头、重定向等的方法

因此,您的测试用例类可以getApplicationServiceLocator()用来获取Zend\ServiceManager\ServiceManager实例或用于获取getRequest()httpZend\Stdlib\RequestInterface请求或Http 响应的实例,所有这些方法都使用内部方法使用您的应用程序配置启动对象然后您需要将方法用于测试用例的方法类来设置您的应用程序配置。getResponse()Zend\Stdlib\ResponseInterfacegetApplication()Zend\Mvc\ApplicationInterface$this->setApplicationConfig()setUp()

我给他们的所有方法作为示例,分配到AbstractControllerTestCase哪个AbstractHttpControllerTestCase类扩展它。

于 2016-01-19T20:28:29.527 回答
0

尝试 :

include  dirname(dirname(dirname(dirname(dirname(__DIR__))))).'/config/application.config.php'
于 2013-06-02T02:10:50.970 回答