How to resolve error within phpunit concerning assertRedirectTo() following zend framework 2.1 example, caused by trailing slash?

StackOverflow https://stackoverflow.com/questions/15938224

Question

After following the Zend Framework 2 "Getting Started" tutorial successfully, I started on the Unit testing example for version 2.1 and, following it verbatim, I get a failure with PHPUnit:

Failed asserting response redirects to "/album", actual redirection is "/album/"

Here's the relevant bit of code from the IndexControllerTest.php file:

public function testAddActionRedirectsAfterValidPost() {

    $albumTableMock = $this->getMockBuilder('Album\Models\AlbumTable')
                           ->disableOriginalConstructor()
                           ->getMock();

    $albumTableMock->expects($this->once())
                   ->method('saveAlbum')
                   ->will($this->returnValue(null));

    $serviceManager = $this->getApplicationServiceLocator();
    $serviceManager->setAllowOverride(true);
    $serviceManager->setService('Album\Models\AlbumTable', $albumTableMock);

    $postData = array('title' => 'Led Zeppelin III', 'artist' => 'Led Zeppelin');
    $this->dispatch('/album/add', 'POST', $postData);
    $this->assertResponseStatusCode(302);

    $this->assertRedirectTo('/album');
}

Here's what I have within the addAction() function within AlbumController.php:

            // Redirect to list of albums
            return $this->redirect()->toRoute('album');

The .htaccess file is the one that came with the Skeleton Application and to be thorough, I've tested that in the browser, http://localhost/zf2-tut/album and http://localhost/zf2-tut/album/ both resolve properly and that in the process of adding an entry, it does indeed redirect me back to the url with the trailing slash.

I know this might come off as just a bit persnickety but I'd like to learn the proper way to resolve an issue such as this.

I know I can change the assertion test to include the trailing slash but since the example doesn't follow that and the toRoute() method does not have the trailing slash, I assume that maybe I've made a mistake in my code or environment somewhere and I assume it's bad practice to have a test deviate from what it's testing.

What's the best way to handle this? If I made a change somewhere that causes the url to resolve with the trailing slash, I actually prefer that in this case but want my code to be clean and not leave any ambiguity about it so I'd want any bits about the route to clearly indicate the trailing slash is expected.

FYI, I made a small change in my folder structure and namespaces after following the tutorial, in changing "Model" to "Models" as a matter of personal preference. That in no way impacts this issue (afaik) but I wanted to point that out so it's not a red herring.


Edit: Shortly after I posted my question, with a bit more legwork I realized how the trailing slash is being appended to my route in this case and posted that in an answer. However, per my answer, I would like to understand why Zend Framework 2 is appending the slash when it's supposedly optional and also, how to properly test for it with PHPUnit.

Was it helpful?

Solution

I guess typing all this out jogged something in my memory as I remembered something odd about the routing config from the tutorial when I went through it several days ago.

Sure enough, in Routing and controllers, the example displayed currently shows:

'router' => array(
    'routes' => array(
        'album' => array(
            'type'    => 'segment',
            'options' => array(
                'route'    => '/album[/][:action][/:id]',
                'constraints' => array(
                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                    'id'     => '[0-9]+',
                ),
                'defaults' => array(
                    'controller' => 'Album\Controller\Album',
                    'action'     => 'index',
                ),
            ),
        ),
    ),
),

Here, the route shows the trailing slash after album encapsulated on it's own, which allows for optional matching. However, the paragraph immediately following the example, plus several comments, make reference to the route previously being /album[/:action][/:id]. The current implementation has the effect of redirecting to the route with a trailing slash. Despite being optional, the controller puts it there so it fails the phpunit test (which judging by the tutorial section's comments, used to be in this portion of the tutorial but now has it's own separate section).

I've verified that changing the route to the older example does indeed redirect without a trailing slash and therefore the phpunit test passes but I then lose my ability to optionally route to this section with a trailing slash. I would prefer to be able to optionally match on this.

So, the "How is this happening?" question has been resolved but I would really like to know how to test for an optional match or if I should just revise the assertion test to check for a trailing slash here. Also, why does Zend\Mvc (or whichever relevant part of the framework, if otherwise) tack on the trailing slash if it's optional?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top