Ric*_*nop 10 php phpunit doctrine-orm zend-framework2
这是我的情况.我正在开发Zend Framework 2应用程序.我正在使用Doctrine模块与MySQL数据库进行通信.它在应用程序中工作正常,我可以从我的控制器内的服务定位器加载实体管理器.
但是在我的控制器单元测试中,服务定位器不存在,因此处理数据库的所有测试都失败,并显示如下错误消息:
致命错误:
get()在第19行的/Users/richardknop/Projects/myproject/module/Api/src/Api/Controller/UserController.php中调用非对象的成员函数
我把问题缩小到这个方法:
$this->getServiceLocator()
Run Code Online (Sandbox Code Playgroud)
哪个适用于我的控制器,但在单元测试中返回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',
),
),
);
Run Code Online (Sandbox Code Playgroud)
我的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',
),
),
),
),
);
Run Code Online (Sandbox Code Playgroud)
在我的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'
),
),
),
),
Run Code Online (Sandbox Code Playgroud)
在我的控制器中,我有这个方法来获取实体管理器:
private $_em;
private function _getEntityManager()
{
if (null === $this->_em) {
$this->_em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
}
return $this->_em;
}
Run Code Online (Sandbox Code Playgroud)
现在我的单元测试.这是bootstrap文件:
<?php
chdir(dirname(__DIR__));
include __DIR__ . '/../init_autoloader.php';
return Zend\Mvc\Application::init(include 'config/application.config.php');
Run Code Online (Sandbox Code Playgroud)
我的控制器测试的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);
}
Run Code Online (Sandbox Code Playgroud)
然后,示例控制器单元测试如下所示:
public function testGetListHttpStatusCode()
{
$response = $this->_controller->dispatch($this->_request);
$this->assertEquals(405, $response->getStatusCode());
}
Run Code Online (Sandbox Code Playgroud)
所有未连接到数据库的测试都在通过.我使用实体管理器的测试失败了,但是出现此错误:
致命错误:
get()在第19行的/Users/richardknop/Projects/myproject/module/Api/src/Api/Controller/UserController.php中调用非对象的成员函数
这是第19行:
$this->_em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
Run Code Online (Sandbox Code Playgroud)
它失败的原因是$this->getServiceLocator()回报NULL.
任何想法如何解决这个问题?
不要这样做你的bootstrap.php
return Zend\Mvc\Application::init(include 'config/application.config.php');` in your
Run Code Online (Sandbox Code Playgroud)
但是像这样:
chdir('/path/to/application/root');
// if you're using composer to install zf2
include_once 'vendor/autoload.php';
// if not using composer initialize your custom autoloading here
$configuration = include('config/application.config.php');
$serviceManager = new ServiceManager(new ServiceManagerConfig(
isset($configuration['service_manager']) ? $configuration['service_manager'] : array()
));
$serviceManager->setService('ApplicationConfig', $configuration);
$serviceManager->setFactory('ServiceListener', 'Zend\Mvc\Service\ServiceListenerFactory');
$moduleManager = $serviceManager->get('ModuleManager');
$moduleManager->loadModules();
$serviceManager->setAllowOverride(true);
$application = $serviceManager->get('Application');
$event = new MvcEvent();
$event->setTarget($application);
$event->setApplication($application)
->setRequest($application->getRequest())
->setResponse($application->getResponse())
->setRouter($serviceManager->get('Router'));
Run Code Online (Sandbox Code Playgroud)
然后,您可以在测试用例中创建静态方法来设置和获取事件......
namespace My;
class TestCase extends \Some\Basic\TestCase
{
protected static $_mvcEvent;
public static function setMvcEvent(MvcEvent $e) {
self::$_mvcEvent = $e;
}
public static function getMvcEvent() {
return self::$_mvcEvent;
}
}
Run Code Online (Sandbox Code Playgroud)
...并从bootstrap.php文件中注入它
My\TestCase::setMvcEvent($event);
Run Code Online (Sandbox Code Playgroud)
并且在你的setUp测试方法中只需做这样的事情
$this->_controller = new UserTokenController;
$this->_controller->setEvent(self::getMvcEvent());
$this->_controller->setServiceLocator(
self::getMvcEvent()->getApplication()->getServiceManager()
);
Run Code Online (Sandbox Code Playgroud)
还将event-> application中的请求等注入到控制器中......
| 归档时间: |
|
| 查看次数: |
4531 次 |
| 最近记录: |