Quantcast
Channel: Richard Knop » TDD
Viewing all articles
Browse latest Browse all 2

How to unit test redirecting in Zend Framework 2

$
0
0

I’ve been working with Zend Framework 2 last couple of weeks and so far I like it better than the legacy Zend Framework. Proper namespaces and separate bootstrap for each module are nice features. I am still learning all the new features so I will be documenting some helpful ideas.

One problem I had today was I needed to write a unit test for a controller action which under certain condition redirects to a different action using the redirect helper:

$this->redirect->roToute('routeName', array('controller' => 'index', 'action' = 'index'));

Unit testing a controller action was not a problem, I figured that out a week or two ago. In order to write an assertion for redirection, you will need to create a new instance of Zend\Mvc\Router\SimpleRouteStack and add routes you are testing for to it. Then attach the router to Zend\Mvc\MvcEvent.

So include few classes from Zend library plus the controller you want to test:

use MyModule\Controller\IndexController,
    Zend\Http\Request,
    Zend\Http\Response,
    Zend\Mvc\MvcEvent,
    Zend\Mvc\Router\RouteMatch,
    Zend\Mvc\Router\SimpleRouteStack,
    Zend\Mvc\Router\Http\Segment,

Then put this inside your PHPUnit test case’s setUp method:

public function setUp()
{
    $this->_controller = new IndexController;
    $this->_request = new Request;
    $this->_response = new Response;

    $this->_event = new MvcEvent();

    $routeStack = new SimpleRouteStack;
    $route = new Segment('/mymodule/[:controller/[:action/]]');
    $routeStack->addRoute('mymodule', $route);
    $this->_event->setRouter($routeStack);

    $routeMatch = new RouteMatch(array('controller' => 'index', 'action' => 'index'));
    $routeMatch->setMatchedRouteName('admin');
    $this->_event->setRouteMatch($routeMatch);

    $this->_controller->setEvent($this->_event);
}

After you have done all that, there are two ways how to assert a redirection has actually happened.

First, you can test for a 302 HTTP status:

public function testIndexActionRedirectsByHttpStatus()
{
    $this->_controller->dispatch($this->_request, $this->_response);
    $this->assertEquals(302, $this->_response->getStatusCode());
}

Second, you can check for the Location header:

public function testIndexActionRedirectsToCorrectUri()
{
    $this->_controller->dispatch($this->_request, $this->_response);
    $this->assertEquals('/mymodule/mycontroller/myaction/', $this->_event->getResponse()->getHeaders()->get('Location')->getUri());
}

Ideally use both assertions to be sure.


Viewing all articles
Browse latest Browse all 2

Trending Articles