Zend Framework 2 Doctrine 2模块 - 控制器单元测试中没有服务定位器

时间:2012-09-14 21:15:42

标签: php doctrine-orm phpunit zend-framework2

这是我的情况。我正在开发Zend Framework 2应用程序。我正在使用Doctrine模块与MySQL数据库进行通信。它在应用程序中工作正常,我可以从我的控制器内的服务定位器加载实体管理器。

但是在我的控制器单元测试中,服务定位器不存在,因此处理数据库的所有测试都失败,并显示如下错误消息:

  

致命错误:在第19行的/Users/richardknop/Projects/myproject/module/Api/src/Api/Controller/UserController.php中调用非对象上的成员函数get()

我已将问题缩小到这种方法:

$this->getServiceLocator()

哪个适用于我的控制器,但在单元测试中返回NULL。

这是我的application.config.php:

<?php

return array(
    'modules' => array(
        'DoctrineModule',
        'DoctrineORMModule',
        'Api',
    ),
    'module_listener_options' => array(
        'config_glob_paths' => array(
            'config/autoload/{,*.}{global,local}.php',
        ),
        'module_paths' => array(
            './module',
            './vendor',
        ),
    ),
);

我的local.php文件包含数据库连接详细信息:

<?php

return array(
    'doctrine' => array(
        'connection' => array(
            'orm_default' => array(
                'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver',
                'params' => array(
                    'host'     => 'localhost',
                    'port'     => '3306',
                    'user'     => 'root',
                    'password' => 'root',
                    'dbname'   => 'mydb',
                ),
            ),
        ),
    ),
);

在我的module.config.php中,我有:

'doctrine' => array(
    'driver' => array(
        __NAMESPACE__ . '_driver' => array(
            'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
            'cache' => 'array',
            'paths' => array(__DIR__ . '/../src/' . __NAMESPACE__ . '/Entity')
        ),
        'orm_default' => array(
            'drivers' => array(
                __NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
            ),
        ),
    ),
),

在我的控制器中,我有这种方法来获取实体管理器:

private $_em;

private function _getEntityManager()
{
    if (null === $this->_em) {
        $this->_em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
    }
    return $this->_em;
}

现在我的单位测试了。这是bootstrap文件:

<?php

chdir(dirname(__DIR__));
include __DIR__ . '/../init_autoloader.php';
return Zend\Mvc\Application::init(include 'config/application.config.php');

我的控制器测试的setUp方法如下:

public function setUp()
{
    $this->_controller = new UserTokenController;
    $this->_request = new Request;
    $this->_routeMatch = new RouteMatch(array('controller' => 'user'));
    $this->_event = new MvcEvent();
    $this->_event->setRouteMatch($this->_routeMatch);
    $this->_controller->setEvent($this->_event);
}

示例控制器单元测试如下:

public function testGetListHttpStatusCode()
{
    $response = $this->_controller->dispatch($this->_request);
    $this->assertEquals(405, $response->getStatusCode());
}

所有未连接到数据库的测试都在通过。我正在使用实体管理器的测试失败但是出现此错误:

  

致命错误:在第19行的/Users/richardknop/Projects/myproject/module/Api/src/Api/Controller/UserController.php中调用非对象上的成员函数get()

这是第19行:

$this->_em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');

它失败的原因是$this->getServiceLocator()返回 NULL

有任何想法如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

只需扩展您的控制器即可 \ Zend的\测试\ PHPUnit的\控制器\ AbstractHttpControllerTestCase

它的初始服务定位器,并做了很多其他控制器的工作。同样成为可用的控制器断言,响应断言,CSS断言等。 有关示例的详细信息请参见http://framework.zend.com/manual/2.1/en/modules/zend.test.phpunit.html