laravel 测试验证错误的更好方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34767309/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Better way for testing validation errors
提问by vivoconunxino
I'm testing a form where user must introduce some text between let's say 100 and 500 characters.
我正在测试一个表单,用户必须在其中引入一些文本,比如 100 到 500 个字符。
I use to emulate the user input:
我用来模拟用户输入:
$this->actingAs($user)
->visit('myweb/create')
->type($this->faker->text(1000),'description')
->press('Save')
->see('greater than');
Here I'm looking for the greater than
piece of text in the response... It depends on the translation specified for that validation error.
在这里,我正在寻找greater than
响应中的一段文本......这取决于为该验证错误指定的翻译。
How could do the same test without having to depend on the text of the validation error and do it depending only on the error itself?
如何在不依赖验证错误的文本的情况下进行相同的测试,而只依赖于错误本身呢?
Controller:
控制器:
public function store(Request $request)
{
$success = doStuff($request);
if ($success){
Flash::success('Created');
} else {
Flash::error('Fail');
}
return Redirect::back():
}
dd(Session::all()):
dd(会话::全部()):
`array:3 [
"_token" => "ONoTlU2w7Ii2Npbr27dH5WSXolw6qpQncavQn72e"
"_sf2_meta" => array:3 [
"u" => 1453141086
"c" => 1453141086
"l" => "0"
]
"flash" => array:2 [
"old" => []
"new" => []
]
]
采纳答案by Ayo Akinyemi
you can do it like so -
你可以这样做 -
$this->assertSessionHas('flash_notification.level', 'danger');
if you are looking for a particular error or success key.
$this->assertSessionHas('flash_notification.level', 'danger');
如果您正在寻找特定的错误或成功键。
or use
$this->assertSessionHasErrors();
或使用
$this->assertSessionHasErrors();
回答by yuklia
I think there is more clear way to get an exact error message from session.
我认为有更清晰的方法可以从会话中获取确切的错误消息。
/** @var ViewErrorBag $errors */
$errors = request()->session()->get('errors');
/** @var array $messages */
$messages = $errors->getBag('default')->getMessages();
$emailErrorMessage = array_shift($messages['email']);
$this->assertEquals('Already in use', $emailErrorMessage);
Pre-requirements: code was tested on Laravel Framework 5.5.14
前置要求:代码在 Laravel Framework 5.5.14 上测试
回答by Ayo Akinyemi
Your test doesn't have a post call. Here is an example using Jeffery Way's flash package
您的测试没有后期调用。这是使用Jeffery Way 的 flash 包的示例
Controller:
控制器:
public function store(Request $request, Post $post)
{
$post->fill($request->all());
$post->user_id = $request->user()->id;
$created = false;
try {
$created = $post->save();
} catch (ValidationException $e) {
flash()->error($e->getErrors()->all());
}
if ($created) {
flash()->success('New post has been created.');
}
return back();
}
Test:
测试:
public function testStoreSuccess()
{
$data = [
'title' => 'A dog is fit',
'status' => 'active',
'excerpt' => 'Farm dog',
'content' => 'blah blah blah',
];
$this->call('POST', 'post', $data);
$this->assertTrue(Post::where($data)->exists());
$this->assertResponseStatus(302);
$this->assertSessionHas('flash_notification.level', 'success');
$this->assertSessionHas('flash_notification.message', 'New post has been created.');
}
回答by User123456
get the MessageBag object from from session erros and get all the validation error names using $errors->get('name')
从会话错误中获取 MessageBag 对象并使用获取所有验证错误名称 $errors->get('name')
$errors = session('errors');
$this->assertSessionHasErrors();
$this->assertEquals($errors->get('name')[0],"The title field is required.");
This works for Laravel 5 +
这适用于 Laravel 5 +
回答by Yevgeniy Afanasyev
try to split your tests into units, say if you testing a controller function
尝试将您的测试拆分为多个单元,比如您是否在测试控制器功能
you may catch valication exception, like so:
您可能会捕获验证异常,如下所示:
} catch (ValidationException $ex) {
if it was generated manually, this is how it should be generated:
如果它是手动生成的,则应该是这样生成的:
throw ValidationException::withMessages([
'abc' => ['my message'],
])->status(400);
you can assert it liks so
你可以这样断言它
$this->assertSame('my message', $ex->errors()['abc'][0]);
if you cannot catch it, but prefer testing routs like so:
如果你不能抓住它,但更喜欢像这样测试路线:
$response = $this->json('POST', route('user-post'), [
'name' => $faker->name,
'email' => $faker->email,
]);
then you use $response to assert that the validation has happened, like so
然后你使用 $response 来断言验证已经发生,就像这样
$this->assertSame($response->errors->{'name'}[0], 'The name field is required.');
PS
聚苯乙烯
in the example I used
在我使用的例子中
$faker = \Faker\Factory::create();
ValidationException is used liks this
ValidationException 像这样使用
use Illuminate\Validation\ValidationException;
just remind you that you don't have to generate exceptions manually, use validate
method for common cases:
只是提醒您,您不必手动生成异常,validate
对于常见情况使用方法:
$request->validate(['name' => [
'required',
],
]);
my current laravel version is 5.7
我目前的 Laravel 版本是 5.7