2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FormRequestクラスをテストする

Last updated at Posted at 2021-02-20

動機

PHP/Laravelを触り始めて間もないが、HTTPリクエストのバリデーションでFormRequestが便利ということで使っていた。手軽だったのでHTTPテストでテストを書いていたが、非効率な箇所もあったのでFormRequest単体でのテストを書きたかった。

前提

  • PHPUnit 9.5.2
  • Laravel Framework 8.27.0

内容

テスト対象のクラスを定義する

$ php artisan make:request ExampleRequest

authorize() で真を返すようにし、 rules() で適当なバリデーションルールを追加する。

app/Http/Requests/ExampleRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ExampleRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'id' => 'required',
            'name' => 'required',
            'email' => 'required'
        ];
    }
}

テストを書く

テストファイルを作成する。(UnitかFeatureかの議論はここでは取り扱わない)

$ php artisan make:test ExampleTest

方法は以下の通り。 Table Driven Test 風に書きたかったので、データプロバイダを定義している。

  • ExampleTestインスタンスを作成する
  • Validatorインスタンスを作成する。テストデータをテスト関数の引数から、ルールとメッセージはExampleTestインスタンスから渡す
  • バリデータを実行し、その結果を評価する
tests/Feature/ExampleTest.php
<?php

namespace Tests\Feature;

use Illuminate\Support\Facades\Validator;
use Tests\TestCase;
use App\Http\Requests\ExampleRequest;

class ExampleTest extends TestCase
{
    /**
     * @dataProvider validationProvider
     * @return void
     */
    public function testValidation($inData, $outFail, $outMessage)
    {
        $request = new ExampleRequest();
        $rules = $request->rules();
        $messages = $request->messages();
        $validator = Validator::make($inData, $rules, $messages);
        $result = $validator->fails();
        $this->assertEquals($outFail, $result);
        $messages = $validator->errors()->getMessages();
        $this->assertEquals($outMessage, $messages);
    }

    public function validationProvider()
    {
        return [
            'success' => [
                [
                    'id' => 1,
                    'name' => 'aaa',
                    'email' => 'aaaa@example.com',
                ],
                false,
                [],
            ],
            'empty all fields' => [
                [],
                true,
                [
                    'id' => ['The id field is required.'],
                    'name' => ['The name field is required.'],
                    'email' => ['The email field is required.'],
                ],
            ],
        ];
    }
}

注意点

HTTPテストをやめて書く場合、当然ながらそのテストで確認していた点はテストできないので注意(例えば、FormRequestが返すメッセージ構造とHTTPレスポンスの構造は異なるなど。)

参考

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?