Search code examples
unit-testingtestingphpunitlaravel-5

Calling named routes in laravel tests


consider the following:

<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class HomeRouteTest extends TestCase
{
    public function testVisitTheHomePage()
    {
        $response = $this->call('GET', '/');
        $this->assertEquals(200, $response->status());

    }

    public function testVisitTheAboutPage()
    {
        $response = $this->call('GET', '/about');
        $this->assertEquals(200, $response->status());
    }
}

Is there away, not that I have seen documented >.>, to do something like:

$response = $this->call('GET', 'home.about');
$this->assertEquals(200, $response->status());

Or .... Is that how you do it?

The error I get is:

vagrant@scotchbox:/var/www$ phpunit
PHPUnit 4.8.21 by Sebastian Bergmann and contributors.

FF

Time: 3.41 seconds, Memory: 14.25Mb

There were 2 failures:

1) HomeRouteTest::testVisitTheHomePage
Failed asserting that 404 matches expected 200.

/var/www/tests/HomeRouteTest.php:12

2) HomeRouteTest::testVisitTheAboutPage
Failed asserting that 404 matches expected 200.

/var/www/tests/HomeRouteTest.php:19

FAILURES!
Tests: 2, Assertions: 2, Failures: 2.

Solution

  • This is a very late response, but I think what you're looking for is:

    $this->route('GET', 'home.about');
    $this->assertResponseOk(); // Checks that response status was 200
    

    For routes with parameters, you can do this:

    $this->route('GET', 'users.show', ['id' => 3]); // (goes to '/users/3')
    

    I needed this to test some ghastly routes I'm working with, which look like this:

    Route::resource(
        '/accounts/{account_id}/users',
        'AccountsController@users',
        [
            'parameters' => ['account_id'],
            'names'      => [
                'create'  => 'users.create',
                'destroy' => 'users.destroy',
                'edit'    => 'users.edit',
                'show '   => 'users.show',
                'store'   => 'users.store',
                'update'  => 'users.update',
            ]
        ]
    );
    

    To make sure that my routes and redirects went to the right page I did this:

    /**
     * @test
     */
    public function users_index_route_loads_correct_page()
    {
        $account = Account::first();
    
        $response = $this->route('get', 'users.index', ['account_id' => $account->id]);
        $this->assertResponseOk()
            ->seePageIs('/accounts/' . $account->id . '/users');
    }
    

    To make sure I was using the right view file (we all make copy-paste errors, right?), I did this:

    /**
     * @test
     */
    public function users_index_route_uses_expected_view()
    {
        $account = Account::first();
    
        $response = $this->route('get', 'users.index', ['account_id' => $account->id]);
    
        $view = $response->original; // returns View instance
        $view_name = $view->getName();
    
        $this->assertEquals($view_name, 'users.index'); 
    }
    

    If it weren't for the Structure feature in PHPStorm and the documentation from Laravel 4.2 that I stumbled over, I don't think I would have ever figured out how to test those routes. I hope this saves someone else a bit of time.