How can I test a forward in a controller with PHPUnit?
I have two simple modules (A and B), module A call the module B using a forward. here is a simple code that not work :
ModuleA
class ModuleAController extends AbstractRestfulController
{
protected $em;
public function setEntityManager(EntityManager $em)
{
$this->em = $em;
}
public function getEntityManager()
{
if (null === $this->em) {
$this->em
$this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
}
return $this->em;
}
public function getList()
{
$data = array('message' => 'passed by module A');
$forward = $this->forward()->dispatch('ModuleB\Controller\ModuleB');
$data['Message'] = $forward->getVariable('Message');
return new JsonModel($data);
}
}
ModuleB
class ModuleBController extends AbstractRestfulController
{
public function setEntityManager(EntityManager $em)
{
$this->em = $em;
}
public function getEntityManager()
{
if (null === $this->em) {
$this->em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
}
}
public function getList()
{
$data = array('Message'=>'passed by module B');
return new JsonModel($data);
}
}
And this is a test code :
class ModuleAControllerTest extends AbstractHttpControllerTestCase
{
protected $controller;
protected $request;
protected $response;
protected $routeMatch;
protected $event;
protected function setUp()
{
$serviceManager = Bootstrap::getServiceManager();
$this->controller = new ModuleAController();
$this->request = new Request();
$this->routeMatch = new RouteMatch(array());
$this->event = new MvcEvent();
$config = $serviceManager->get('Config');
$routerConfig = isset($config['router']) ? $config['router'] : array();
$router = HttpRouter::factory($routerConfig);
$this->event->setRouter($router);
$this->event->setRouteMatch($this->routeMatch);
$this->controller->setEvent($this->event);
$this->controller->setServiceLocator($serviceManager);
}
public function testModuleAControllerCanBeAccessed()
{
$result = $this->controller->dispatch($this->request);
$response = $this->controller->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals(200, 1+99+100);
}
}
And this is the error message : There was 1 error:
1) ModuleATest\Controller\ModuleAControllerTest::testModuleAControllerCanBeAccessed
Zend\ServiceManager\Exception\ServiceNotCreatedException: An exception was raised while creating "forward"; no instance returned
....
Caused by
Zend\ServiceManager\Exception\ServiceNotCreatedException: Zend\Mvc\Controller\Plugin\Service\ForwardFactory requires that the application service manager has been injected; none found
....
FAILURES!
Tests: 1, Assertions: 0, Errors: 1.
Is there any way to make this code work ??Any idea ??
Thank you.
I have not created mock for plugins yet. I don't know how set new plugin to controller. But mock will be like it.
PHPunit test file
public function testControllerWithMock()
{
/* Result from ModuleBController method getList() */
$forwardResult = new JsonModel(array('Message'=>'passed by module B'));
/* Create mock object for forward plugin */
$forwardPluginMock = $this->getMockBuilder('\Zend\Mvc\Controller\Plugin\Forward')
->disableOriginalConstructor()
->getMock();
$forwardPluginMock->expects($this->once())
->method('dispatch') /* Replace method dispatch in forward plugin */
->will($this->returnValue($forwardResult)); /* Dispatch method will return $forwardResult */
/* Need register new plugin (made mock object) */
$controller->setPluginManager(); /* ??? Set new plugin to controller */
I'm thinking how decide it.
Ok, try it.
$controller->getPluginManager()->injectController($forwardPluginMock);
I don't write PHPUnit tests for controllers. Because controllers must return a view and best solution using Selenium
for testing view. I usually use PHPUnitSelenium
tests for testing it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.