phpunit test returns 302 for bad validation, why not 422 phpunit test returns 302 for bad validation, why not 422 laravel laravel

phpunit test returns 302 for bad validation, why not 422


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.

JSON

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);

AJAX

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']]);