如何在Phalcon单元测试中引导我的依赖注入器服务?

时间:2013-12-27 01:48:27

标签: php unit-testing phpunit phalcon

我浏览了Phalcon文档并完成了PHPUnit的设置和工作。但是,我无法将现有服务引导到单元测试框架中。

目前,我在/public/index.php中加载配置,路由和服务。例如,我正在加载会话库:

$di->set(
    'session',
    function () use ( $config ) {
        $session = new Phalcon\Session\Adapter\Redis(
            ... config ...
        );
    });

现在,在我的应用程序中,我将使用调用$this->session->get( 'user_id' )的代码来使用会话库。我有很多这样的服务 - 一个用于SQL,MongoDB,cookie等。

我遇到的问题是将这些服务正确加载到单元测试类中。 Phalcon文档建议在UnitTestCase类(explained here)中加载我的DI服务,但我真的不想在这个类加载器中重新定义相同的服务。另外,我想以相同的方式使用我的应用程序中的组件;这些组件依赖于延迟加载的服务。

因此,为了尝试这一点,我在单元测试/app/config/services.php初始化脚本中包含相同的TestHelper.php文件,认为我可以使用相同的$ di对象。我的测试用例可以调用$this->di->getSession()->get( 'var' ),但只要我的应用中的某个组件尝试调用$this->session->get( 'var' ),它就会抛出错误:

1) Libraries\SessionTest::testGetSet
Undefined property: Libraries\SessionTest::$session

/home/mike/PhalconProject/app/library/Session.php:25
/home/mike/PhalconProject/tests/libraries/SessionTest.php:13

此错误告诉我,通过依赖项注入器访问Session.php时,我的应用程序会话管理库$this->session->失败。

这里有什么我从根本上做错了吗?我是否需要在单元测试类中重新定义服务?如果我确实需要重新定义它们,我的应用程序是否能够加载它的服务?

2 个答案:

答案 0 :(得分:1)

因此,这里的解决方案似乎是构建应用程序库以静态访问DI服务。

第一步是在/public/index.php/tests/bootstrap.php中设置默认DI:

\Phalcon\DI::setDefault( $di );

现在,在应用程序库(如/app/Library/Auth.php/app/Library/Session.php)中,静态访问服务(more info here in the Phalcon docs):

$session = \Phalcon\DI::getDefault()->getSession();
$session->get( 'user_id' )
...

为了简化这一过程,我设置了一个基本库,我的所有应用程序库都扩展了它。基础库有一种简化此调用的方法。

namespace Base;

use \Phalcon\DI as DI;

class Library extends \Phalcon\Mvc\User\Component
{
    public function getService( $service )
    {
        $func = "get". ucfirst( $service );
        return DI::getDefault()->$func();
    }
}

最后,/app/Library/Session.php将扩展此\Base\Library类,每当我需要方法中的会话服务时,我只需调用:

$session = self::getService( 'session' );

答案 1 :(得分:0)

我已经使用简单的PHPUnit bootstrap.php文件注入了我所有的Phalcon服务(我通常通过调用DI对象获得)(看看PHPUnit的--bootstrap选项)我的bootstrap.php内容是:< / p>

<?php

require_once(__DIR__ . '/../app/config/local_config.php');
$config = include __DIR__ . "/../app/config/config.php";
/**
 * Read auto-loader
 */
include __DIR__ . "/../app/config/loader.php";

/**
 * Read services
 */
include __DIR__ . "/../app/config/services.php";

因此,在我的PHPUnit测试中,我只需要调用$di->get('MyService');