How do you test middleware?

Middleware can be a tricky thing to test. Here's what I did in a recent project.

Joel Clermont
Joel Clermont
2023-10-20

There are a few different ways I've written tests for middleware in my Laravel apps over the years, but none of them felt quite right.

In a recent project, I landed on an approach using a "dummy" route registered right inside my test file, which solved the issues I didn't like with earlier styles of testing.

class SomeMiddlewareClassTest extends IntegrationTestCase
{
    protected function setUp(): void
    {
        parent::setUp();

        Route::get('/dummy-test-route', function () {
            return '';
        })->middleware(['web', SomeMiddlewareClass::class]);
    }

    public function testSuccess(): void
    {
        $user = User::factory()->create();
        
        // some additional setup so that the user passes through middleware successfully

        $this->actingAs($user);

        $response = $this->get('/dummy-test-route');
        $response->assertOk();
    }

    public function testDoesNotHaveCurrentClientRedirects(): void
    {
        $user = User::factory()->create();

        $this->actingAs($user);
        
        // some additional setup so that the user will be redirected with an error

        $this->get('/dummy-test-route')
            ->assertRedirectToRoute('dashboard')
            ->assertSessionHas('error', __('Some middlware error here'));
    }
}

As it turns out, I just rediscovered something people were already doing. Here's a nice write-up of the approach in Kai's blog.

Here to help,

Joel

P.S. Have a burning question about your Laravel app? Pair with us and we'll help you out.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼

Level up your Laravel skills!

Each 2-minute email has real-world advice you can use.