Aquí está mi situación. Estoy desarrollando una aplicación Zend Framework 2. Estoy usando el módulo Doctrine para comunicarme con una base de datos MySQL. Está funcionando bien en la aplicación, puedo cargar el administrador de entidades desde el localizador de servicios dentro de mis controladores.Módulo Zend Framework 2 Doctrine 2 - No hay un localizador de servicio en las pruebas de la unidad controladora
Pero dentro de mis pruebas de unidad de controlador, el localizador de servicio no existe y por lo tanto todas las pruebas que se ocupan de la base de datos no están cumpliendo con el mensaje de error como este:
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
que han reducido el problema a este método :
$this->getServiceLocator()
Que funciona en mis controladores pero devuelve NULL en pruebas unitarias.
Ésta es mi 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',
),
),
);
Mi archivo local.php con detalles de la conexión de base de datos:
<?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',
),
),
),
),
);
En mi module.config.php tengo:
'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'
),
),
),
),
Y en mis controladores tengo este método para obtener el administrador de la entidad:
private $_em;
private function _getEntityManager()
{
if (null === $this->_em) {
$this->_em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
}
return $this->_em;
}
Ahora mis pruebas de la unidad. Aquí está el archivo de arranque:
<?php
chdir(dirname(__DIR__));
include __DIR__ . '/../init_autoloader.php';
return Zend\Mvc\Application::init(include 'config/application.config.php');
Y método de configuración de mis pruebas controlador se parece a:
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 ejemplo de prueba de unidad controladora a continuación, se ve así:
public function testGetListHttpStatusCode()
{
$response = $this->_controller->dispatch($this->_request);
$this->assertEquals(405, $response->getStatusCode());
}
Todas las pruebas que sean no se está conectando a la base de datos. Pruebas en las que estoy usando el administrador de entidades están fallando aunque con este error:
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
Ésta es la línea 19:
$this->_em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
Y la razón por la que está fallando es que $this->getServiceLocator()
vuelve NULL
.
¿Alguna idea de cómo solucionar este problema?
Después de todo he usado un enfoque un poco diferente (pero la idea principal es la misma, simplemente puse más lógica dentro de mi Bootstrap.php para phpunit). Pero el tuyo también funciona. –
mina también hace mucho más, solo la redujo a los requisitos básicos –
Hola Andreas. También estoy usando ZF2 + Doctrine2 y sigo tu método. Mientras se configura el ServiceLocator, parece que el evento no se propaga a los complementos de Controller: el enrutador, por ejemplo, se establece en el serviceLocator pero no en el complemento redirect(). ¿Alguna idea sobre cómo configurar esto? – Ross