Ecco la mia situazione. Sto sviluppando un'applicazione Zend Framework 2. Sto usando il modulo Doctrine per comunicare con un database MySQL. Funziona bene nell'applicazione, posso caricare il gestore di entità dal localizzatore di servizio all'interno dei miei controller.Modulo Zend Framework 2 Doctrine 2 - Nessun localizzatore di servizio nei test dell'unità di controllo
Ma dentro mio test di unità del controller, il localizzatore di servizio non esiste e per questo tutti i test che si occupano con il database non riescono con il messaggio di errore come questo:
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
ho ridotto il problema a questo metodo :
$this->getServiceLocator()
Quale funziona nei miei controller ma restituisce NULL in unit test.
Questo è il mio 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',
),
),
);
Il mio file local.php con i dettagli di connessione al database:
<?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',
),
),
),
),
);
Nel mio module.config.php ho:
'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'
),
),
),
),
E nei miei controller ho questo metodo per ottenere il gestore di entità:
private $_em;
private function _getEntityManager()
{
if (null === $this->_em) {
$this->_em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
}
return $this->_em;
}
Ora la mia unità prova. Ecco il file di bootstrap:
<?php
chdir(dirname(__DIR__));
include __DIR__ . '/../init_autoloader.php';
return Zend\Mvc\Application::init(include 'config/application.config.php');
E metodo di impostazione dei miei test del controller appare come:
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);
}
Un test di unità di controllo esempio appare quindi come:
public function testGetListHttpStatusCode()
{
$response = $this->_controller->dispatch($this->_request);
$this->assertEquals(405, $response->getStatusCode());
}
Tutti i test che sono non si sta connettendo al database. I test in cui mi sto usando gestore di entità non riescono però con questo errore:
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
Questa è la riga 19:
$this->_em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
E la ragione è in mancanza è che $this->getServiceLocator()
rendimenti NULL
.
Qualche idea su come risolvere questo problema?
Dopo tutto, ho usato un approccio leggermente diverso (ma l'idea principale è la stessa, ho solo messo più logica dentro di me Bootstrap.php per phpunit). Ma anche il tuo funziona. –
anche il mio fa molto di più, lo ha semplicemente ridotto ai requisiti di base –
Ciao Andreas. Sto anche usando ZF2 + Doctrine2 e sto seguendo il tuo metodo. Mentre ServiceLocator è impostato, sembra che l'evento non venga propagato ai plug-in Controller: il router, per esempio, è impostato nel serviceLocator ma non nel plugin redirect(). Qualche idea su come impostare questo? – Ross