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?
Laravel 5.4 POST 到 API 重定向 302 而不是返回验证错误