phpunit 测试返回 302 验证错误,为啥不返回 422

Posted

技术标签:

【中文标题】phpunit 测试返回 302 验证错误,为啥不返回 422【英文标题】:phpunit test returns 302 for bad validation, why not 422phpunit 测试返回 302 验证错误,为什么不返回 422 【发布时间】:2016-05-03 16:41:18 【问题描述】:

我有一个请求类,对于发布请求失败。当我用 ajax 调用它时,我得到一个 422,因为验证规则失败。但是当我使用 phpunit 对具有相同值的相同路由进行测试时,它会返回 302。

我也没有收到诸如“需要字段 foobar”之类的错误消息,只有 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

【问题讨论】:

如果使用 ajax,验证失败会返回 422。如果不使用,验证失败会返回 302 重定向。您的测试要么需要将请求作为 ajax,要么遵循重定向。我们无法提供进一步的帮助,因为您没有发布任何代码、展示您的测试等。 【参考方案1】:

FormRequest 上的验证失败时,它会检查请求是否为 ajax 或是否接受 json 响应。如果是这样,它将返回带有 422 状态码的 json 响应。如果没有,它将返回一个重定向到指定的 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 标头。为此,您可以继续使用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);

【讨论】:

成功了。还可以使用'HTTP_X-Requested-With' => 'XMLHttpRequest' 设置标题与normal $this->post @patricus 谢谢队友。过去 8 小时我一直在尝试解决此问题,但无法解决。 $this->json 是关键。 +1【参考方案2】:

对于 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 中设置的那些标头可以在任何时候以相同的方式扩展。举个例子:

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

【讨论】:

以上是关于phpunit 测试返回 302 验证错误,为啥不返回 422的主要内容,如果未能解决你的问题,请参考以下文章

lumen - 为啥 PHPUnit 注册测试返回 405?

Symfony PHPUnit 测试不验证用户

Laravel 5.4 POST 到 API 重定向 302 而不是返回验证错误

为啥在asp.net中使用自定义404页面时不存在的页面返回302状态

无法在 ajax 中处理 302 重定向,为啥? [复制]

有没有学习ThinkPHP的呢?找不到模块为啥返回302呢?如何返回404