phpunit test returns 302 验证错误,为什么不是 422

phpunit test returns 302 for bad validation, why not 422

我有一个请求 class,但是 post 请求失败了。当我用 ajax 调用它时,我得到一个 422,因为验证规则失败。但是当我使用 phpunit 测试具有相同值的相同路由时,它 returns a 302.

我也没有收到 "field foobar is required" 之类的错误消息,只有 302。

那么我怎样才能得到错误消息来检查它们是否相等?

这是我的测试代码:

//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

FormRequest 上的验证失败时,它会检查请求是否为 ajax 或者它是否接受 json 响应。如果是这样,它将 return 一个带有 422 状态代码的 json 响应。如果没有,它会 return 重定向到指定的 url (以前,默认情况下)。因此,为了获得您正在寻找的失败响应 (422),您需要发出 json 请求或 ajax 请求。

JSON

要发出 json 请求,您应该使用 json() 方法:

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

还有 getJson()postJson()putJson()patchJson()deleteJson() 快捷方法,如果您认为这看起来比传递方法更简洁作为参数。

//post exam
$this->postJson('modul/foo/exam', [
        'date' => '2016-01-01'
    ])
    ->assertResponseStatus(200);

AJAX

要发出ajax请求,您需要在ajax中添加headers。为此,可以继续使用post()方法:

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

对于 Laravel 6 这有效:

withHeaders(['Accept' => 'application/json'])

举个例子:

 $this->withHeaders(['Accept' => 'application/json'])
     ->post(route('user.register'), $data)
     ->assertStatus(422)
     ->assertJson($expectedResponse);

如果多个测试需要类,可以放在tests/TestCase.php中,所有测试用例都会设置。

举个例子:

public function setup(): void
{
    $this->withHeaders([
        'Accept' => 'application/json',
        'X-Requested-With' => 'XMLHttpRequest'
    ]);
}

tests/TestCase.php中设置的headers可以用同样的方法在任意点进行扩展。例如:

$this->withHeaders([
    'Authorization' => 'Bearer '.$responseArray['access_token']
]);