Validation 测试验证错误的更好方法
我正在测试一个表单,其中用户必须引入一些介于100到500个字符之间的文本 我用于模拟用户输入:Validation 测试验证错误的更好方法,validation,laravel,testing,phpunit,Validation,Laravel,Testing,Phpunit,我正在测试一个表单,其中用户必须引入一些介于100到500个字符之间的文本 我用于模拟用户输入: $this->actingAs($user) ->visit('myweb/create') ->type($this->faker->text(1000),'description') ->press('Save') ->see('greater than'); 在这里,我要查找的是响应中的大于的文本片段。。。它取决于为该验证错误指定的翻译 如何在不依赖
$this->actingAs($user)
->visit('myweb/create')
->type($this->faker->text(1000),'description')
->press('Save')
->see('greater than');
在这里,我要查找的是响应中的大于的文本片段。。。它取决于为该验证错误指定的翻译
如何在不依赖验证错误文本的情况下执行相同的测试,并且只依赖于错误本身
控制器:
public function store(Request $request)
{
$success = doStuff($request);
if ($success){
Flash::success('Created');
} else {
Flash::error('Fail');
}
return Redirect::back():
}
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();
}
dd(会话::all()):
你可以这样做-
$this->assertSessionHas('flash_notification.level','danger')代码>如果您正在查找特定错误或成功密钥
或使用
$this->assertSessionHasErrors()代码>您的测试没有post调用。下面是一个使用
控制器:
public function store(Request $request)
{
$success = doStuff($request);
if ($success){
Flash::success('Created');
} else {
Flash::error('Fail');
}
return Redirect::back():
}
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();
}
测试:
从会话erros获取MessageBag对象,并使用$errors->get('name')
这适用于Laravel 5+我认为有更清晰的方法可以从会话中获得准确的错误消息
/** @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上进行了测试
试着把你的测试分成几个单元,比如你测试一个控制器功能
您可能会捕获有效性异常,如下所示:
} 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
,即使我真的遇到了验证错误,也无法工作。assertSessionHasErrors()验证为false<代码>会话缺少密钥:断言false为true失败的错误代码>可能与laravel 5.1有关,而不是我的控制器,看:@AyoAkinyemi您显示的不是验证错误测试
,而是闪存消息测试
按下保存按钮(->按下('save')
)也会发送post请求。顺便说一句,您尝试了您的断言,但现在由于以下标记而失败:testing.ERROR:exception'illumb\Session\tokenmischexception'位于/var/www/html/anuncios.com/vendor/laravel/framework/src/illumb/Foundation/Http/Middleware/VerifyCsrfToken.php:53
添加这些特征。。。数据库事务,没有测试类的中间件。好的,(我也可以do$this->be($some_user);
)。尽管如此,断言还是失败了,没有抛出flash消息,发布后我用会话的var_转储更新了问题。可能是因为错误是由FormRequest传递的,而不是专门调用FlashFacade`嗯……有趣。。。有什么方法可以聊天吗?如果我们一直评论聊天可能会自动打开,idk任何其他方法您是如何使request()
函数在unittest中工作的?@YevGeniyafanasev您在调用测试中的$this->post()
和$this->get()
等后调用request()
。您将调用刚刚发出的请求。>我正在使用phpunit 7.5和Lumen 5.8-当对请求或规则使用单元测试时,您可以执行$this->expectException$this->expectException('light\Validation\ValidationException')
和$this->expectExceptionMessage=“名称字段是必需的”代码>-另请注意,异常不包含验证消息(我只得到<代码>给定数据无效<代码>)异常不包含验证消息-由于单个异常可能包含多个验证失败的信息,因此异常包含一组消息<代码>$ex->errors()
$request->validate(['name' => [
'required',
],
]);