Edited at
LaravelDay 6

Laravel でカスタムバリデーションとそのテスト

More than 1 year has passed since last update.

本記事は Laravel Advent Calendar 2016 の 6 日目の記事です。


はじめに

公式のカスタムバリデーションのドキュメントが今ひとつ分かりにくいので、手順をまとめることにした。

今回はサンプルとして ふりがな のバリデーションを作成する。

※以前に書いた通常バリデーションの応用

http://qiita.com/komatzz/items/422bcba9847ca3a79fe9


環境


  • CentOS 7

  • PHP 7

  • Laravel 5.3


カスタムバリデーション作成手順


サービスプロバイダー作成


php artisan make:provider ValidatorServiceProvider


作成されたクラスを以下のように編集。


app/Providers/ValidatorServiceProvider.php


namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Domain\CustomValidator;

class ValidatorServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/

public function boot()
{
\Validator::resolver(function ($translator, $data, $rules, $messages) {
return new CustomValidator($translator, $data, $rules, $messages);
});
}

/**
* Register the application services.
*
* @return void
*/

public function register()
{
//
}
}



作成したサービスプロバイダーを設定ファイルに追加


config/app.php

'providers' => [

...

App\Providers\ValidatorServiceProvider::class,

...



カスタムバリデーションのロジックを書くファイルを作成する

今回はdomainというディレクトリを作成し、その下にCustomValidator.phpを作成した。


domain/CustomValidator.php

namespace Domain;

class CustomValidator extends \Illuminate\Validation\Validator
{
/**
* ふりがなのバリデーション
*
* @param $attribute
* @param $value
* @param $parameters
* @return bool
*/

public function validateKana($attribute, $value, $parameters)
{
if (mb_strlen($value) > 100) {
return false;
}

if (preg_match('/[^ぁ-んー]/u', $value) !== 0) {
return false;
}

return true;
}
}



オートロードの設定

composer.json の psr-4 設定に にdomainディレクトリ配下をオートロードできるように追加する

※これに気づかなくてハマった


composer.json

...

"autoload": {
"psr-4": {
"App\\": "app/",
"Domain\\": "domain/",
}
}

...



エラーメッセージファイルに追加


resources/lang/ja/validation.php

return [

...

'kana' => ':attributeはひらがなで入力をしてください。',

...

'attributes' => [
...

'family_name_kana' => 'ふりがな(せい)',
'given_name_kana' => 'ふりがな(めい)',

...
],



カスタムバリデーションを使う

使い方は通常のバリデーションと同じで、

'family_name_kana' => 'required|kana',

のように使いたいバリデーションを|区切りで指定すれば良い。


app/Http/Controllers/RegistersController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Validator;

class RegistersController extends Controller
{
...

public function confirm(Request $request, $registerToken)
{
\Validator::make(
[
'family_name_kana' => trim($request->get('family_name_kana')),
'given_name_kana' => trim($request->get('given_name_kana')),
],
[
'family_name_kana' => 'required|kana',
'given_name_kana' => 'required|kana',
]
}->validate();
}
return view('registers/registers_confirm');

...
}



バリデーション実施結果

valid_kana.png

ふりがな(せい)をカタカナで POST したので、ちゃんと引っかかっている。


テストコード作成

ちゃんとバリデーションできているかどうかテストするコードを書く。


tests/domain/validation/KanaTest.php

<?php

/**
* かなのバリデーションのテストクラス
*/

namespace Tests\Domain\Validation;

use Validator;

class KanaTest extends \TestCase
{
/**
* 正常系テスト
*
* @dataProvider successParamsProvider
* @param array $values
*/

public function testSuccess($values)
{
$validator = \Validator::make(
[
'family_name_kana' => $values,
'given_name_kana' => $values,
],
[
'family_name_kana' => 'required|kana',
'given_name_kana' => 'required|kana',
]
);

$this->assertTrue(
$validator->passes()
);
}

/**
* 正常系パラメータ用のデータプロバイダー
*
* @return array
*/

public function successParamsProvider()
{
return [
'ひらがな' => [
'やきにくていしょく',
],
'大きな文字列(かなは100文字まで)' => [
str_repeat('あ', 100)
],
];
}

/**
* 異常系テスト
*
* @dataProvider failParamsProvider
* かなに不適切な文字が入力されている
*
* @param array $values
*/

public function testFail($values)
{
$validator = \Validator::make(
[
'family_name_kana' => $values,
'given_name_kana' => $values,
],
[
'family_name_kana' => 'required|kana',
'given_name_kana' => 'required|kana',
]
);

$this->assertTrue(
$validator->fails()
);
}

/**
* 異常系パラメータ用のデータプロバイダー
*
* @return array
*/

public function failParamsProvider()
{
return [
'数字' => [
1,
],
'漢字' => [
'焼肉定食',
],
'カタカナ' => [
'ヤキニクテイショク',
],
'大きな文字列(かなは100文字まで)' => [
str_repeat('あ', 101),
],
'NULL' => [
null,
],
'空' => [
'',
],
'スクリプト' => [
'<script>alert(1);</script>',
],
'\'' => [
'\'',
],
'/' => [
'/',
],
'<' => [
'<',
],
'¥' => [
'¥',
],
];
}
}



解説


  • ひらがな かつ、100文字以内かどうかをテストしている

  • PHPUnit のデータプロバイダーという機能を使うと簡潔にテストコードが書けて、失敗したときにどこで失敗したのか分かりやすい

image


ひとこと

これでバリデーション処理に関しては、ほとんど対応できるようになった。