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.