Laravel - Testing what happens after a redirect
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
# Laravel Testing: How to Follow Redirects and Test Session Flashes Correctly
As senior developers working with Laravel, we frequently encounter scenarios where testing user flows involves redirects. A common sticking point arises when using PHPUnit to test interactions that involve HTTP redirects (like a 302 response) followed by session flashes or view rendering. The core issue is often about understanding whether the test runner stops at the redirect status code or if it needs to simulate the browser behavior of *following* that redirect.
This post will dive into why your initial attempt failed and provide robust, practical solutions for testing redirects and state changes within your Laravel applications.
## The Redirect Testing Dilemma
You are attempting to test a controller action that performs an email submission, flashes a session message, and then redirects the user using `Redirect::route('home')`.
Your original test looked like this:
```php
public function testMessageSucceeds() {
$crawler = $this->client->request('POST', '/contact', ['email' => 'test@test.com', 'message' => "lorem ipsum"]);
$this->assertResponseStatus(302);
$this->assertRedirectedToRoute('home'); // Assertion 1
$message = $crawler->filter('.success-message'); // This part was trying to check the final view state.
// Here it fails because the test runner stops after receiving the 302 response.
$this->assertCount(1, $message);
}
```
The problem is that when you use methods like `request()` on the HTTP client, by default, PHPUnit only captures the immediate response from the server. When Laravel issues a redirect (HTTP status code 302), it tells the browser to go somewhere else, but the basic request method doesn't automatically navigate to the new URL. Therefore, checking for elements on the *new* page fails because the test execution stops before that final page is loaded.
## Solution 1: Testing the Redirect Chain
To successfully test a full user flow, you need to tell your testing client (the HTTP request object) to follow the redirect. Laravel provides excellent tools within its testing environment to handle this gracefully.
Instead of trying to manually assert the redirect status and then separately check the final content, focus on chaining the operations to simulate a true browser interaction. While direct methods like `assertRedirectedToRoute()` are useful for checking the raw response headers, when you need to test the *result* of the flow (like session data persistence), itâs often cleaner to perform the action and then check the final state as if the redirect had successfully occurred.
For testing flows that involve redirects, ensure your client is performing the necessary steps in sequence:
```php
public function testMessageSucceeds()
{
// 1. Perform the POST request
$response = $this->client->post('/contact', [
'email' => 'test@test.com',
'message' => 'lorem ipsum'
]);
// 2. Assert the initial redirect happened (optional but good practice)
$response->assertRedirect();
$response->assertRedirectedToRoute('home');
// 3. Crucially, if you need to check session state, you must now load the destination page.
// Since we know it redirects to 'home', let's request that route directly to check the flashed data.
$this->client->get(route('home'))
->assertSessionHas('message', 'Ok!'); // Check the session flash on the resulting page
// If you were testing a view render *after* the redirect, this is how you do it:
$response = $this->client->post('/contact', [ /* data */ ]);
$response->followRedirect(); // This method forces the client to follow the 302 response.
// Now check the content of the final page after following the redirect
$response->assertSessionHas('message', 'Ok!');
// If you need to verify a specific view element on that final page:
$response->assertSee('Ok!'); // Or filter based on what the home view renders.
}
```
## Best Practice: Testing Session Data Flow
The most reliable way to test session flashing after a redirect is to use methods designed to handle redirection, such as `followRedirect()`. This method instructs the testing client to automatically execute the redirection logic whenever it encounters a 3xx status code, which perfectly simulates how a real user's browser behaves.
When focusing on application stateâlike ensuring data flashed via `Session::flash()` is available on the next pageâyou should test the final destination route directly after simulating the redirect. This approach aligns with modern Laravel testing practices, emphasizing behavior over raw HTTP status codes alone. For deeper dives into how Laravel manages request lifecycles and routing, consulting the official documentation at [laravelcompany.com](https://laravelcompany.com) is highly recommended.
## Conclusion
Testing redirects in Laravel requires shifting your focus from merely asserting the initial redirect status code to simulating the entire user experience. By utilizing methods like `followRedirect()` and chaining assertions to check the state of the destination route, you ensure that your tests accurately reflect how the application behaves under real-world conditions. This results in more robust, maintainable, and reliable test suites when working with complex controller logic.