admin管理员组

文章数量:1356289

One of my automated tests is returning status code 302 whereas it should return 422.

CategoryTest.php

class CategoryTest extends TestCase {
    use RefreshDatabase;

    ...

    public function test_categories_cannot_create_without_payload_should_receive_422() {
        $response = $this->post(route('categories.store'), []);

        $response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY);
        $response->assertJson([
            'message',
            'errors',
        ]);
    }

    ...
}

I have also created a global class for handling this situation.

namespace App\Http\Requests;

use Illuminate\Http\Response;
use Illuminate\Validation\ValidationException;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;

class FormRequest extends \Illuminate\Foundation\Http\FormRequest {
    protected function failedValidation(Validator $validator) {
        if ($this->expectsJson()) {
            throw new HttpResponseException(
                response()->json([
                    'message' => 'Please check the following error(s)',
                    'errors'  => (new ValidationException($validator))->errors(),
                ], Response::HTTP_UNPROCESSABLE_ENTITY)
            );
        }

        parent::failedValidation($validator);
    }
}

One of my automated tests is returning status code 302 whereas it should return 422.

CategoryTest.php

class CategoryTest extends TestCase {
    use RefreshDatabase;

    ...

    public function test_categories_cannot_create_without_payload_should_receive_422() {
        $response = $this->post(route('categories.store'), []);

        $response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY);
        $response->assertJson([
            'message',
            'errors',
        ]);
    }

    ...
}

I have also created a global class for handling this situation.

namespace App\Http\Requests;

use Illuminate\Http\Response;
use Illuminate\Validation\ValidationException;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;

class FormRequest extends \Illuminate\Foundation\Http\FormRequest {
    protected function failedValidation(Validator $validator) {
        if ($this->expectsJson()) {
            throw new HttpResponseException(
                response()->json([
                    'message' => 'Please check the following error(s)',
                    'errors'  => (new ValidationException($validator))->errors(),
                ], Response::HTTP_UNPROCESSABLE_ENTITY)
            );
        }

        parent::failedValidation($validator);
    }
}

Share Improve this question edited Apr 1 at 10:49 VLAZ 29.1k9 gold badges63 silver badges84 bronze badges asked Mar 28 at 5:55 Mr.SinghMr.Singh 1,8176 gold badges31 silver badges62 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 1

Along with @Tatachiblob's answer. I have found some other ways to fix this issue.

$response = $this
    ->withHeader('accept', 'application/json')
    ->post(route('categories.store'), []);

Or

$response = $this->withHeaders([
    'accept' => 'application/json',
])->post(route('categories.store'), []);

Or

$response = $this->post(route('categories.store'), [], [
    'accept' => 'application/json',
]);

Or

$response = $this->json('post', route('categories.store'), []); // currently using

Hope this will be able to save some time for someone.

Let me try helping.

I assume that your postman request has a header Accept: application/json, and that makes the $this->expectsJson() to true.

To make this work in your phpunit, you have to set the request header with the following:

public function test_categories_cannot_create_without_payload_should_receive_422() {
    $response = $this
        ->withHeader('accept', 'application/json')
        ->post(route('categories.store'), []);

    $response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY);
    $response->assertJson([
        'message',
        'errors',
    ]);
}

This should pass the assert status with 422 instead of 302.

Hope you find this helpful.

Regards,

本文标签: Laravel 9x different status code while automated testingStack Overflow