Reputation: 25267
I have a controller that after submitting a email, performs a redirect to the home, like this:
return Redirect::route('home')->with("message", "Ok!");
I am writing the tests for it, and I am not sure how to make phpunit to follow the redirect, to test the success message:
public function testMessageSucceeds() {
$crawler = $this->client->request('POST', '/contact', ['email' => '[email protected]', 'message' => "lorem ipsum"]);
$this->assertResponseStatus(302);
$this->assertRedirectedToRoute('home');
$message = $crawler->filter('.success-message');
// Here it fails
$this->assertCount(1, $message);
}
If I substitute the code on the controller for this, and I remove the first 2 asserts, it works
Session::flash('message', 'Ok!');
return $this->makeView('staticPages.home');
But I would like to use the Redirect::route
. Is there a way to make PHPUnit to follow the redirect?
Upvotes: 37
Views: 39750
Reputation: 1060
You can get PHPUnit to follow redirects with:
Modern Laravel (>= 5.5.19):
$this->followingRedirects();
Older Laravel (< 5.4.12):
$this->followRedirects();
Usage:
$response = $this->followingRedirects()
->post('/login', ['email' => '[email protected]'])
->assertStatus(200);
Note: This needs to be set explicitly for each request.
For versions between these two:
See https://github.com/laravel/framework/issues/18016#issuecomment-322401713 for a workaround.
Upvotes: 68
Reputation: 1696
//routes/web.php
Route::get('/', function () {
return redirect()->route('users.index');
})->name('index');
//on my TestClass
$response = $this->get('/');
$response->assertStatus(302);
$response->assertRedirect(route('users.index'));
Upvotes: 1
Reputation: 796
Laravel 8 tested
$response = $this->post'/contact', ['email' => '[email protected]', 'message' => "lorem ipsum"]);
$response->assertStatus(302);
$response->assertRedirect('home');
$this->followRedirects($response)->assertSee('.success-message');
//or
$this->followRedirects($response)->assertSee('Ok!');
Worked for me, hoped it helps.
Upvotes: 12
Reputation: 4695
Since Laravel 5.5 to test redirect you can use assertRedirect:
/** @test */
public function store_creates_claim()
{
$response = $this->post(route('claims.store'), [
'first_name' => 'Joe',
]);
$response->assertRedirect(route('claims.index'));
}
Upvotes: 4
Reputation: 1
For Laravel 5.6, you can set
$protected followRedirects = true;
within your class file for your test case
Upvotes: -4
Reputation: 131
You can tell crawler to follow a redirect this way:
$crawler = $this->client->followRedirect();
so in your case that would be something like:
public function testMessageSucceeds() {
$this->client->request('POST', '/contact', ['email' => '[email protected]', 'message' => "lorem ipsum"]);
$this->assertResponseStatus(302);
$this->assertRedirectedToRoute('home');
$crawler = $this->client->followRedirect();
$message = $crawler->filter('.success-message');
$this->assertCount(1, $message);
}
Upvotes: 8