I have a request class that fails for a post request. When I call it with ajax I get an 422 because the validation rules failed. But when I use phpunit for test for the same route with same values, it returns a 302.
I also get no error messages like "field foobar is required" just the 302.
So how can I get the error messages to check if they are equals or not?
Here is my testcode:
//post exam
$this->post('modul/foo/exam', [
'date' => '2016-01-01'
])
->assertResponseStatus(200);
//post exam again
$this->post('modul/foo/exam', [
'date' => '2016-01-01'
])
->assertResponseStatus(302); //need to get 422 with th errors because its an api
When the validation on the FormRequest
fails, it checks to see if the request was ajax or if it accepts a json response. If so, it will return a json response with the 422 status code. If not, it will return a redirect to a specified url (previous, by default). So, in order to get the response on failure you're looking for (422), you need to make a json request or an ajax request.
To make a json request, you should use the json()
method:
//post exam
$this->json('POST', 'modul/foo/exam', [
'date' => '2016-01-01'
])
->assertResponseStatus(200);
//post exam again
$this->json('POST', 'modul/foo/exam', [
'date' => 'some invalid date'
])
->assertResponseStatus(422);
There are also getJson()
, postJson()
, putJson()
, patchJson()
, and deleteJson()
shortcut methods if you think that looks cleaner than passing the method as a parameter.
//post exam
$this->postJson('modul/foo/exam', [
'date' => '2016-01-01'
])
->assertResponseStatus(200);
To make an ajax request, you need to add in the ajax headers. For this, you can continue to use the post()
method:
//post exam
$this->post('modul/foo/exam', [
'date' => '2016-01-01'
], ['HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'])
->assertResponseStatus(200);
//post exam again
$this->post('modul/foo/exam', [
'date' => 'some invalid date'
], ['HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'])
->assertResponseStatus(422);
For Laravel 6 this works:
withHeaders(['Accept' => 'application/json'])
For an example:
$this->withHeaders(['Accept' => 'application/json'])
->post(route('user.register'), $data)
->assertStatus(422)
->assertJson($expectedResponse);
If it's needed for multiple test classes, it can be placed in tests/TestCase.php
and it will be set up for all test cases.
For an example:
public function setup(): void
{
$this->withHeaders([
'Accept' => 'application/json',
'X-Requested-With' => 'XMLHttpRequest'
]);
}
Those headers set in tests/TestCase.php
can be extended at any point by the same way. For an example:
$this->withHeaders([
'Authorization' => 'Bearer '.$responseArray['access_token']
]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With