ryanzec
ryanzec

Reputation: 28060

Unit Testing Zend Controller Just Exits

So I have this unit test class:

class HomeControllerTest extends ControllerTestCase
{
    public function testLoginAction()
    {
        $this->dispatch('/home/login');
        $this->assertController('home');
        $this->assertAction('login');
        $this->assertQueryCount('div.login', 1);
    }

    public function testProcessloginAction()
    {
        $this->getRequest()
        ->setMethod('POST')
        ->setPost(array("username" => "[email protected]",
                                       "password" => "password"));
        $this->dispatch('/home/processlogin');

        $session = new Zend_Session_Namespace('session');
        $this->assertEquals($session->isLoggedIn, true);
        $this->assertRedirectTo('/home');
    }
}

And this is the output of the test:

root@ubuntu:/mnt/hgfs/app# phpunit --stderr
PHPUnit 3.5.15 by Sebastian Bergmann.

.root@ubuntu:/mnt/hgfs/app#

The first test runs fine however the second test just exits right before the $this->dispatch('/home/processlogin'); line. I don't know why but the only thing I can see that is different is that the home/processlogin does a redirect.

Has anyone experienced this with ZF 1.11.x (test against 1.11.7 and 1.11.11)?

Upvotes: 2

Views: 839

Answers (3)

Jess Telford
Jess Telford

Reputation: 13220

Internally, the Zend framework calls exit; after setting the headers to do the redirect.

However, when run via the Zend Controller Test cases, the framework disables this exit;, and allows the calling code (eg; the test case) to continue executing.

There are two situations you need to handle:

1. There is no actual redirection.

Since the page is not actually redirected, you must now use the assertRedirectTo() test method:

assert that a redirect has occurred, and that the value of the Location header is the $url provided.

public function testRedirectHeadersSent()
{
    $this->dispatch('/user');
    $this->assertRedirectTo('/user/view');
}

2. The Action doesn't exit on redirection.

To stop execution of the code within the action, you must ensure you return from the action when you redirect:

public function userAction()
{
    // ... Some code
    return $this->getHelper('Redirector')->goToRoute(array ('id' => $id), 'userView');

    // ... Will no longer execute the following:
    var_dump("Never gets here");
}

Upvotes: 0

t j
t j

Reputation: 7324

One issue I've come across when testing redirects in Zend Framework is that they often fail if the redirect is not exiting the action properly. This does not seem to affect the redirect in a browser but causes it to fail when running the code through PHPUnit on the CLI.

Rather than use:

$this->_redirect('home');

Try returning the redirect so that it exits the action properly:

return $this->_redirect('home');

Upvotes: 0

Gediminas
Gediminas

Reputation: 864

It would be useful if you could show us the processlogin action code.

From what I can see in the unit test, it can fail because the redirect in controller can stop the script execution. Disable the redirection in the controller to see if it is the problem.

Upvotes: 1

Related Questions