我正在测试一个表单,用户必须在100到500个字符之间引入一些文本。
我用来模拟用户输入:
$this->actingAs($user)
->visit('myweb/create')
->type($this->faker->text(1000),'description')
->press('Save')
->see('greater than');
在这里,我正在寻找响应中的greater than
文本...这取决于为该验证错误指定的翻译。
如何在不依赖于验证错误的文本的情况下进行相同的测试,并且仅根据错误本身进行测试?
控制器:
public function store(Request $request)
{
$success = doStuff($request);
if($success)
{
Flash::success('Created');
}else{
Flash::error('Fail');
}
return Redirect::back():
}
DD(会话::所有()):
`array:3 [
"_token" => "ONoTlU2w7Ii2Npbr27dH5WSXolw6qpQncavQn72e"
"_sf2_meta" => array:3 [
"u" => 1453141086
"c" => 1453141086
"l" => "0"
]
"flash" => array:2 [
"old" => []
"new" => []
]
]
答案 0 :(得分:6)
我认为有更明确的方法可以从会话中获取确切的错误消息。
/** @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);
预先要求:代码在Laravel Framework 5.5.14上进行了测试
答案 1 :(得分:4)
你可以这样做 -
$this->assertSessionHas('flash_notification.level', 'danger');
如果您正在寻找特定错误或成功密钥。
或使用
$this->assertSessionHasErrors();
答案 2 :(得分:0)
您的测试没有发布电话。以下是使用Jeffery Way's flash package
的示例控制器:
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();
}
测试:
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.');
}
答案 3 :(得分:0)
从会话错误中获取MessageBag对象,并使用$errors->get('name')
获取所有验证错误名称
$errors = session('errors');
$this->assertSessionHasErrors();
$this->assertEquals($errors->get('name')[0],"The title field is required.");
适用于Laravel 5 +
答案 4 :(得分:0)
尝试将测试分成多个单元,例如是否测试控制器功能
您可能会发现配偶异常,如下所示:
} catch (ValidationException $ex) {
如果是手动生成的,则应采用以下方式生成:
throw ValidationException::withMessages([
'abc' => ['my message'],
])->status(400);
您可以这样称呼
$this->assertSame('my message', $ex->errors()['abc'][0]);
如果您无法捕获它,而是喜欢像这样测试溃败:
$response = $this->json('POST', route('user-post'), [
'name' => $faker->name,
'email' => $faker->email,
]);
然后您使用$ response断言验证已发生,就像这样
$this->assertSame($response->errors->{'name'}[0], 'The name field is required.');
PS
在我使用的示例中
$faker = \Faker\Factory::create();
ValidationException用于此
use Illuminate\Validation\ValidationException;
只是提醒您,您不必手动生成异常,对于常见情况,请使用validate
方法:
$request->validate(['name' => [
'required',
],
]);
我当前的laravel版本是5.7