简体   繁体   中英

Zend Framework 2 how to test forward in controller using phpunit?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM