Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
2
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

Laravel で FromRequest のバリデーションをテストする

Laravel の FormRequest クラスを利用すると各フィールドのバリデーションルールを array の形で定義することができます。

<?php

namespace App\Http\Requests\UserRegistration;

use Illuminate\Foundation\Http\FormRequest;

class UserRegistrationFormRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'name' => [
                'required',
                'string',
                'min:2',
                'regex:/^[A-Za-z0-9]+$/',
            ],
            'password' => [
                'required',
                'string',
                'min:8',
                'regex:/[a-z]/',
                'regex:/[A-Z]/',
                'regex:/[0-9]/',
                'regex:/@$!%*#?&/',
            ],
        ];
    }
}

一つ一つのルールをテストするメリットは特にないと思いますが、上記のような複数ルールの組み合わせやカスタムバリデーションを検証するために Unit Test を作成する際の Tips を紹介します。

テストコード

ベースとなるメソッドは Stack Overflow から拝借しています(というか、この記事の要点はこの方法の紹介です!)。
これをベースに汎用的な FormRequest 用の TestCase クラスを作ってみます。

<?php

namespace Tests\Unit\App\Requests\Base;

use Illuminate\Foundation\Testing\TestCase;

abstract class BaseFormRequestTestCase extends TestCase
{
    /**
     * @var array
     */
    protected $rules;
    /**
     * @var \Validator
     */
    protected $validator;

    public function setUp(): void
    {
        parent::setUp();
        $this->setRules();
        $this->validator = $this->app['validator'];
    }

    /**
     * 子クラスで Request Class が持つ rules を set する。
     */
    abstract protected function setRules(): void;

    protected function getFieldValidator($field, $value)
    {
        return $this->validator->make(
            [$field => $value],
            [$field => $this->rules[$field]]
        );
    }

    protected function validateField($field, $value)
    {
        return $this->getFieldValidator($field, $value)->passes();
    }
}

これを継承した形で TestCase を作成すれば比較的シンプルにバリデーションのテストを書くことができます。

<?php

namespace Tests\Unit\App\Requests\UserRegistration\UserRegistrationFormRequest;

use App\Http\Requests\UserRegistration\UserRegistrationFormRequest;
use Tests\Unit\App\Requests\Base\BaseFormRequestTestCase;

class UserRegistrationFormRequestTest extends BaseFormRequestTestCase
{
    protected function setRules(): void
    {
        $this->rules = (new UserRegistrationFormRequest())->rules();
    }

    public function testNameRules() {
        $this->assertFalse($this->validateField('name', null));
        $this->assertFalse($this->validateField('name', 'a'));
        $this->assertTrue($this->validateField('name', 'ab'));
        $this->assertTrue($this->validateField('name', 'AB'));
        $this->assertTrue($this->validateField('name', '01'));
        $this->assertTrue($this->validateField('name', 'aA0'));
        $this->assertFalse($this->validateField('name', 'ab@'));
        $this->assertFalse($this->validateField('name', 'ab cd'));
    }

    public function testPasswordRules() {
        $this->assertFalse($this->validateField('password', null));
        $this->assertFalse($this->validateField('password', 'abAB01@'));
        $this->assertTrue($this->validateField('password', 'abAB01@$'));
        $this->assertFalse($this->validateField('password', 'abcABC012'));
        $this->assertFalse($this->validateField('password', 'ABC012@$!'));
        $this->assertFalse($this->validateField('password', '012@$!abc'));
        $this->assertFalse($this->validateField('password', '@$!abcABC'));
        $this->assertFalse($this->validateField('password', 'ab AB 01 @$'));
    }
}

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
2
Help us understand the problem. What are the problem?