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

Ranx99's avatar

How to test routes that are protected by a middleware?

Let's say I have a group of routes which are protected by a middleware:

Route::group(['middleware' => 'verified'], function () {
    Route::get('/profile', 'ProfileController@show')->name('profile.show');
    Route::get('/settings', 'SettingsController@show')->name('settings.show');
});

How can I test that these routes are protected by verified middleware? If I write those tests, are they considered as feature tests or unit tests?

0 likes
5 replies
alanholmes's avatar

@ranx99

I would test middleware using the $this->actingAs($user)->get(route('profile.show')) function to test that the user is not able to access it if they do not meet the conditions of the verified middleware.

So using this method it would be a feature test

1 like
Sergiu17's avatar
// given I'm logged in with an unverified account

// when I go to /profile

// I should be redirected to /verify

And this is a future/functional test.

Ranx99's avatar

Thanks for your help, since I have many routes, what do you think about this approach?

/** @test */
public function front_routes_has_verified_middleware()
{
    $routes = Route::getRoutes();

    foreach ($routes as $route) {
        if (Str::startsWith($route->getName(), 'front.')) {
            $flag = in_array('verified', $route->middleware());
        }
    }

    $this->assertTrue($flag);
}
Sti3bas's avatar

@ranx99 this test doesn't guarantee that all needed routes will be protected as you can accidentally move some routes to the other group. I would recommend to follow @alanholmes and @sergiu17 solutions instead.

alanholmes's avatar
Level 35

@ranx99

As this is a very common test for me, I have had added it to a trait RestrictUnverifiedEmailAccessViaGetRequests which I then include in the required tests (I have similar ones for Post, Put and Delete), and this the trait:

namespace Tests\Feature\Traits;

use App\User;

trait RestrictUnverifiedEmailAccessViaGetRequests
{
    /** @test */
    public function users_with_unverified_emails_cannot_access_via_get()
    {
        $user = factory(User::class)
            ->states('unverified')
            ->create();

        $this->actingAs($user);

        foreach ($this->routesToTest['get'] as $route => $params) {
            $this->get(route($route, $params))
                 ->assertRedirect(route('verification.notice'));
        }
    }
}

Then in my tests, I just have to use the traits, and setup the routes to test, eg:

class DashboardTest extends TestCase
{
    use RefreshDatabase;
    use RestrictGuestAccessViaGetRequests;

    protected $routesToTest = [
        'get' => [
            'dashboard' => [],
        ],
    ];
}

(this is if you used named routes, but you could easily modify)

1 like

Please or to participate in this conversation.