Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

kingmaker_bgp's avatar

Testing Laravel Route hitting a Controller Method

What is the best way to test a Route hitting a Controller Method as specified in the routes/web.php file?

Consider I have a route as following in the routes/web.php file.

use App\Http\Controller\DashboardController.php;

Route::get('dashboard', [DashboardController::class, 'index'])
     ->middleware('auth');

Questions

Please provide the best possible ways to write Tests for the following:

  1. Ensuring the Route is hitting the Controller Action.
  2. The auth Middleware is applied / acted on this route.

P.S I want to make sure I didn't making any mistakes in the Route files in the Future.

0 likes
11 replies
munazzil's avatar

Just use below command in your CMD you can get every single details of the App with controller and web.php Routes,

   php artisan route:list
1 like
kingmaker_bgp's avatar

Hi @munazzil, you didn't get my question. I know the Artisan command available to list the routes....

I want to write a PHPUnit test that ensures that the "Given Route hits the Specified Controller Action (Method) and it has the Specified middlewares applied"

mstrauss's avatar

Something like this should do it:


    /** @test */
    public function userCanAccessDashboard()
    {
        $user = factory(User::class)->create();

        $response = $this->actingAs($user)
            ->get('/dashboard');

        $response->assertStatus(200);
        $response->assertViewHas(['item_from_view', 'another_item_from_view']);
    }

    /** @test */
    public function guestCanNotVisitLoggedInPages()
    {
        $response = $this->get('/dashboard');

        $response->assertRedirect('/login');

    }

I think this meets your criteria. You can be sure that the controller action is hit by confirming that variables it creates and passed to the view (assuming it returns a view) end up in the view, i.e.

$response->assertViewHas(['item_from_view', 'another_item_from_view']);
2 likes
Mahaveer's avatar

@kingmaker_bgp Kindly check your controller method namespace

use App\Http\Controller\DashboardController;

Route::get('dashboard', [DashboardController::class, 'index'])
     ->middleware('auth');
kingmaker_bgp's avatar

Hi @mstrauss , Your Answer is good for checking the Application Feature about getting the correct view and ensuring that the auth Middleware is applied.

I want to test the URL Route is being Handled by the Expected Controller Action (Irrespective of the Action Logic / Implementation). To be very precise, I want to hook the Test into the Laravel Routing layer and ensure that the correct Action method is invoked.

Goal / Motivation

Write a Loosely Coupled Test to check the Route calls the expected Action method.

mstrauss's avatar

@kingmaker_bgp I see what you are saying, but in essence, you are testing the Laravel Framework at that point, which is already thoroughly tested by many excellent developers. Your tests should test the unique things that your application does, not the Framework (IMO).

kingmaker_bgp's avatar

Yes @mstrauss, I didn't wish to test the Laravel Framework, But my concern is

I might accidentally change the routes/web.php file in the Future and the correct Controller Action may not be called.... I would like to prevent this using a Test for the Defined Routes.

This will tell exactly the Error and I don't want to reverse engineer other Failing Tests.

kingmaker_bgp's avatar
kingmaker_bgp
OP
Best Answer
Level 8

Hi guys, finally found a working way for Testing Routes hitting the Expected Controller Action using the Mockery::mock()

<?php

namespace Tests\Routes;

use Tests\TestCase;
use Mockery;
use App\Http\Controllers\Auth\LoginController;

class AuthRoutesTest extends TestCase
{
    /**
     * @test
     */
    public function test_login_view_route() {
        $controller_class = LoginController::class;
        $action = 'showLoginForm';
        $route = route('login');

        // Mock
        $controller_mocked = Mockery::mock($controller_class . '['. 'callAction' .']');
        $this->app->instance($controller_class, $controller_mocked);

        // Assert
        $controller_mocked->shouldReceive('callAction')->withArgs([$action, Mockery::any()])->once();

        // Visit Route
        $this->get($route);

    }

This provides a little more confident over my code.

PS

Any improvements to the Test are appreciated and welcomed.

Hope this helps someone :smile:

Please or to participate in this conversation.