ここは私の状況です。私はZend Framework 2アプリケーションを開発しています。私はDoctrineモジュールを使ってMySQLデータベースと通信しています。アプリケーションで正常に動作しています。コントローラ内のサービスロケータからエンティティマネージャをロードできます。Zend Framework 2 Doctrine 2モジュール - コントローラユニットテストのサービスロケータなし
しかし、私のコントローラユニットテスト内で、サービスロケータが存在せず、そのためのデータベースを扱うすべてのテストは、このようなエラーメッセージで失敗している:
Fatal error: Call to a member function
get()
on a non-object in /Users/richardknop/Projects/myproject/module/Api/src/Api/Controller/UserController.php on line 19
私はこの方法に問題が絞られています:
$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ファイルのファイル:私は私のmodule.config.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',
),
),
),
),
);
:
'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;
}
私のユニットがテストします。ここでは、ブートストラップファイルには、次のとおりです。私のコントローラテストの
<?php
chdir(dirname(__DIR__));
include __DIR__ . '/../init_autoloader.php';
return Zend\Mvc\Application::init(include 'config/application.config.php');
とセットアップ方法は以下のようになります。
public function testGetListHttpStatusCode()
{
$response = $this->_controller->dispatch($this->_request);
$this->assertEquals(405, $response->getStatusCode());
}
あるすべてのテストを:
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);
}
例コントローラユニットテストは、次にようになります。データベースに接続していない場合は合格となります。私は、エンティティマネージャを使用しています試験は、このエラーにかかわらず、失敗する:
Fatal error: Call to a member function
get()
on a non-object in /Users/richardknop/Projects/myproject/module/Api/src/Api/Controller/UserController.php on line 19
これは、19行目です:
$this->_em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
そして、それは失敗だ理由は$this->getServiceLocator()
戻りNULL
ということです。
このアイデアを解決する方法はありますか?あなたは、イベントを設定して得るためにあなたのテストケースの静的メソッドを作成することができ
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'));
:
結局のところ、私はちょっとしたアプローチを使いました(しかし、主なアイデアは同じです。 phpunitのBootstrap.php)。しかし、あなたもうまくいきます。 –
鉱山も多くのことを行い、ちょうどそれを基本的な要件に減らしました –
こんにちはアンドレアス。私はZF2 + Doctrine2も使用しており、あなたの方法に従っています。 ServiceLocatorが設定されている間、イベントはControllerプラグインには伝播していないようです。たとえばルータはserviceLocatorでは設定されていますが、redirect()プラグインでは設定されていません。これを設定する方法に関するアイデアはありますか? – Ross