tezu memo blog

日々行った作業をメモしていきます

Laravel Validation Test Requestクラスのみを対象

はじめに

バリデーションのテストをしたいのですが、 テスト 5.2 Laravel だと、bladeファイルも必要なので ちょっと違うんですよね

テスト対象

一からコードを書くのが面倒なので、以下を購入してイジって遊んでます

codecanyon.net

BlogRequestはjosh adminのコード

<?php

namespace App\Http\Requests;

use App\Http\Requests\Request;

class BlogRequest extends Request {

    /**
    * 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 [
            'title' => 'required|min:3',
            'content' => 'required|min:3',
            'blog_category_id' => 'required',
        ];
    }

}

テストケース

サービスコンテナにMockのリクエストをセットするのがポイント

<?php
use App\Http\Requests\BlogRequest;
use Illuminate\Http\Exception\HttpResponseException;
use Illuminate\Http\Request;

class BlogRequestTest extends TestCase
{
// php artisan make:test App\Http\Requests\BlogRequestTest

    /**
     * @return void
     * @test
     */
    public function 未入力()
    {
        try {
            // App::makeでvalidationが実行されてしまう。。
            App::make(BlogRequest::class);
        } catch (HttpResponseException $e) {
            $messages = $this->getMessages();
            $this->assertEquals('The title field is required.', $messages['title'][0]);
            $this->assertEquals('The content field is required.', $messages['content'][0]);
            $this->assertEquals('The blog category id field is required.', $messages['blog_category_id'][0]);
        } catch (Exception $e) {
            $this->fail("HttpResponseExceptionが発生すべき");
        }
    }

    /**
     * @return void
     * @test
     */
    public function 最小値_直前の値()
    {
        $this->bindRequest([
            'title' => '11',
            'content' => '22',
            'blog_category_id' => 1
        ]);

        try {
            App::make(BlogRequest::class);
        } catch (HttpResponseException $e) {
            $messages = $this->getMessages();
            $this->assertEquals('The title must be at least 3 characters.', $messages['title'][0]);
            $this->assertEquals('The content must be at least 3 characters.', $messages['content'][0]);
            $this->assertFalse(isset($messages['blog_category_id']));
        } catch (Exception $e) {
            $this->fail("HttpResponseExceptionが発生すべき");
        }
    }

    /**
     * @return void
     * @test
     */
    public function 最小値()
    {
        $this->bindRequest([
            'title' => '111',
            'content' => '222',
            'blog_category_id' => 1
        ]);

        try {
            App::make(BlogRequest::class);
        } catch (HttpResponseException $e) {
            $this->fail("全て正常値。HttpResponseExceptionは発生しない");
        } catch (Exception $e) {
            $this->fail("全て正常値。Exceptionは発生しない");
        }
    }

    /**
     * @param $params array
     */
    private function bindRequest($params)
    {
        // vendor/laravel/framework/src/Illuminate/Foundation/Providers/FoundationServiceProvider.php
        // でサービスコンテナからrequestを取り出してRequestクラスにパラメータをセットしている
        //
        // $this->initializeRequest($request, $app['request']);
        //
        // protected function initializeRequest(FormRequest $form, Request $current)
        // $form->initialize(
        //    $current->query->all(), $current->request->all(), $current->attributes->all(),
        //    $current->cookies->all(), $files, $current->server->all(), $current->getContent()
        // );

        // サービスコンテナにMockのリクエストをセット
        App::instance('request', Request::create('', 'POST', $params, [], [], [], []));
    }

    /**
     * @return array
     */
    private function getMessages()
    {
        /**
         * @var \Illuminate\Support\ViewErrorBag $viewErrorBag
         * @var \Illuminate\Support\MessageBag $messageBag
         */
        $viewErrorBag = Session::get('errors');
        $messageBag = $viewErrorBag->getBag('default');
        return $messageBag->getMessages();
    }
}