phpunit - Autenticación de prueba de unidad ZF2
zend-framework2 zfcuser (2)
Estaba aprendiendo acerca de las pruebas de unidad e intenté resolver el siguiente problema:
Zend/ServiceManager/ServiceManager::get was unable to fetch or create an instance for zfcUserAuthentication
... usando la única respuesta dada en:
Pruebas unitarias simples de ZF2 para un controlador que usa ZfcUser
Así que mi función de configuración se ve igual. Desafortunadamente, me sale el mensaje de error:
Zend/Mvc/Exception/InvalidPluginException: Plugin of type Mock_ZfcUserAuthentication_868bf824 is invalid; must implement Zend/Mvc/Controller/Plugin/PluginInterface
Se produce en esta parte del código (se divide en mi código de la misma manera):
$this -> controller->getPluginManager()
->setService(''zfcUserAuthentication'', $authMock); // Error refers to this line.
El objeto $ authMock aparentemente no está implementando la interfaz de plugin, que necesito implementar para pasar a setService.
¿No se supone que $ authMock se pase allí para su uso en pruebas unitarias? ¿Debo utilizar un método setService diferente (orientado a pruebas de unidad)?
Necesito una forma de manejar el inicio de sesión en mi aplicación, o la prueba de mi unidad no tiene sentido.
Gracias por cualquier consejo.
=== Editar (02/02/2013) ===
Quería concentrarme en esta parte para aclarar, ya que creo que esta es el área problemática:
// Getting mock of authentication object, which is used as a plugin.
$authMock = $this->getMock(''ZfcUser/Controller/Plugin/ZfcUserAuthentication'');
// Some expectations of the authentication service.
$authMock -> expects($this->any())
-> method(''hasIdentity'')
-> will($this->returnValue(true));
$authMock -> expects($this->any())
-> method(''getIdentity'')
-> will($this->returnValue($ZfcUserMock));
// At this point, PluginManager disallows mock being assigned as plugin because
// it will not implement plugin interface, as mentioned.
$this -> controller->getPluginManager()
->setService(''zfcUserAuthentication'', $authMock);
Si el simulacro no maneja las implementaciones necesarias, ¿de qué otra manera puedo pretender iniciar sesión?
Acabo de hacer un ejemplo para el complemento FlashMessenger. Solo debe usar el ControllerPluginManager para anular el ControllerPlugin. Asegúrese de que su aplicación bootstrap llame a setApplicationConfig () ;
<?php
namespace SimpleTest/Controller;
use Zend/Test/PHPUnit/Controller/AbstractHttpControllerTestCase;
class SimpleControllerTest extends AbstractHttpControllerTestCase {
public function testControllerWillAddErrorMessageToFlashMessenger()
{
$flashMessengerMock = $this->getMockBuilder(''/Zend/Mvc/Controller/Plugin/FlashMessenger'', array(''addErrorMessage''))->getMock();
$flashMessengerMock->expects($this->once())
->method(''addErrorMessage'')
->will($this->returnValue(array()));
$serviceManager = $this->getApplicationServiceLocator();
$serviceManager->setAllowOverride(true);
$serviceManager->get(''ControllerPluginManager'')->setService(''flashMessenger'', $flashMessengerMock);
$this->dispatch(''/error/message'');
}
}?>
Tiene un problema con el espacio entre nombres o su autocargador.
Cuando está creando su simulacro, no se encuentra la definición de clase de ZfcUser/Controller/Plugin/ZfcUserAuthentication
. Así que PHPUnit crea un simulacro que solo extiende esta clase para su prueba. Si la clase estaba disponible, PHPUnit usará la clase real para extenderse al hacer su simulacro, que luego usará las clases / interfaces primarias.
Puede ver esta lógica aquí: https://github.com/sebastianbergmann/phpunit-mock-objects/blob/master/PHPUnit/Framework/MockObject/Generator.php
if (!class_exists($mockClassName[''fullClassName''], $callAutoload) &&
!interface_exists($mockClassName[''fullClassName''], $callAutoload)) {
$prologue = ''class '' . $mockClassName[''originalClassName''] . "/n{/n}/n/n";
if (!empty($mockClassName[''namespaceName''])) {
$prologue = ''namespace '' . $mockClassName[''namespaceName''] .
" {/n/n" . $prologue . "}/n/n" .
"namespace {/n/n";
$epilogue = "/n/n}";
}
$cloneTemplate = new Text_Template(
$templateDir . ''mocked_clone.tpl''
);
Por lo tanto, si no hay una clase o interfaz, PHPUnit creará una en sí misma para que el simulacro cumpla con las sugerencias de tipo del nombre de la clase original. Sin embargo, las clases o interfaces principales no se incluirán porque PHPUnit no las conoce.
Esto podría deberse a no incluir el espacio de nombres adecuado en su prueba o tener un problema en su cargador automático. Es difícil decirlo sin ver realmente el archivo de prueba completo.
Alternativamente, en lugar de ZfcUser/Controller/Plugin/ZfcUserAuthentication
, puedes ZfcUser/Controller/Plugin/ZfcUserAuthentication
Zend/Mvc/Controller/Plugin/PluginInterface
en tu prueba y pasarlo al administrador de complementos. Aunque si está insinuando el plugin en su código, su prueba aún no funcionará.
//Mock the plugin interface for checking authorization
$authMock = $this->getMock(''Zend/Mvc/Controller/Plugin/PluginInterface'');
// Some expectations of the authentication service.
$authMock -> expects($this->any())
-> method(''hasIdentity'')
-> will($this->returnValue(true));
$authMock -> expects($this->any())
-> method(''getIdentity'')
-> will($this->returnValue($ZfcUserMock));
$this -> controller->getPluginManager()
->setService(''zfcUserAuthentication'', $authMock);