Php 如何测试验证错误在laravel单元测试中抛出准确的错误和消息
如何在验证错误中抛出的php单元中测试特定的验证错误? 使用下面的代码,我们可以检查会话是否有错误,但不能检查确切的错误Php 如何测试验证错误在laravel单元测试中抛出准确的错误和消息,php,unit-testing,laravel-5,phpunit,tdd,Php,Unit Testing,Laravel 5,Phpunit,Tdd,如何在验证错误中抛出的php单元中测试特定的验证错误? 使用下面的代码,我们可以检查会话是否有错误,但不能检查确切的错误 $this->assertSessionHasErrors(); 得到答案了吗 $errors = session('errors'); $this->assertSessionHasErrors(); $this->assertEquals($errors->get('name')[0],"Your error messag
$this->assertSessionHasErrors();
得到答案了吗
$errors = session('errors');
$this->assertSessionHasErrors();
$this->assertEquals($errors->get('name')[0],"Your error message for validation");
$errors是在引发验证错误时存储在laravel会话中的MessageBag对象
使用$errors->get('name')可以将所有验证错误视为一个数组
assertSessionHasErrors
可以接收一个数组:
在我看来,还有一种更优雅的方式: 如果通过类GeneralException引发异常,则可以在单元测试中检查会话是否存在引发异常的flash_危险 让我们做一个实际的例子:我们想测试管理员不能激活已经激活的目录项 测试功能
public function an_admin_cannot_activate_an_activated_catalogue()
{
$catalogue = factory(Catalogue::class)->states('active')->create();
$response = $this->get("/admin/questionnaire/catalogue/{$catalogue->id}/activate");
$response->assertSessionHas(['flash_danger' => __('The catalogue item is already activated.')]);
}
型号/复制功能
public function an_admin_cannot_activate_an_activated_catalogue()
{
$catalogue = factory(Catalogue::class)->states('active')->create();
$response = $this->get("/admin/questionnaire/catalogue/{$catalogue->id}/activate");
$response->assertSessionHas(['flash_danger' => __('The catalogue item is already activated.')]);
}
如果它被激活,我们抛出一个异常,然后可以通过测试函数进行检查
public function activate(Catalogue $catalogue) : Catalogue
{
if ($catalogue->is_active) {
throw new GeneralException(__('The catalogue item is already activated.'));
}
$catalogue->is_active = 1;
$activated = $catalogue->save();
if($activated) {
return $catalogue;
}
}
您可以结合使用
assertStatus
和assertJson
...
->assertStatus(422)
->assertJson([
'errors' => [
'field' => [
'Error message'
]
]
]);
您可以使用$response->assertSessionHasErrors('键') 下面是required属性的一个示例
$response = $this->json('POST', '/api/courses', $this->data([
'name' => '',
'api_token' => $this->user->api_token
]));
$response->assertSessionHasErrors('name');
您可以添加一个额外的断言,以确保没有向数据库添加任何条目,在本例中为“assert no course was added”
对于多个必需的属性,可以使用如下循环:
collect(['name', 'description', 'amount'])->each(function ($field) {
$response = $this->json('POST', '/api/courses', $this->data([
$field => '',
'api_token' => $this->user->api_token
]));
$response->assertSessionHasErrors($field);
$this->assertCount(0, Course::all());
});
实际上,使用
dd()
和session('errors')
由于错误包存储在会话中,您可以在单元测试中添加dd(会话('errors')
,以查看缺少哪些字段
最后,您可以通过添加
$response->assertSessionHasErrors('field_name');
我正在使用phpunit 7.5和Lumen 5.8的可能副本来编写更合适的测试-当对请求或规则使用单元测试时,您可以执行$this->expectException$this->expectException('Illumb\Validation\ValidationException');
和$this->expectExceptionMessage=“名称字段是必需的”
-另请参阅注意:异常不包含验证消息!它只是说给定的数据无效
您实际上不需要将错误放入会话来测试验证器。您可以从ValidationException
中获取错误,例如$ex->errors()
这里只使用键。这不会测试错误消息,只测试字段有一条消息。我认为这可能在某一点上是正确的,但从6.x开始,除了字段/键本身,您还可以传递值来测试特定的错误消息。在Laravel文档中:对于Laravel 6.x(可能还有更早的版本),检查assertSessionHasErrors
:您可能需要在测试的setUp()
$key=config('session.keys.errors');$errors=session($key)中启动会话;
collect(['name', 'description', 'amount'])->each(function ($field) {
$response = $this->json('POST', '/api/courses', $this->data([
$field => '',
'api_token' => $this->user->api_token
]));
$response->assertSessionHasErrors($field);
$this->assertCount(0, Course::all());
});