LaravelでJSONリクエスト、JSONレスポンスの単体テストを行う

# 目次
Laravelの記事一覧は下記
[PHPフレームワークLaravelの使い方](https://qiita.com/toontoon/items/c4d0371e504c37f6576e)

# Laravelバージョン
動作確認はLaravel Framework 7.19.1で行っています

# 前提条件
[eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)](https://qiita.com/toontoon/items/76fa7f8845b20776077c)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っています

[Laravelで入力値エラーチェック(validate)を実装する](https://qiita.com/toontoon/items/abf5c52eb0c3fe11003c)
本記事は上記の内容を理解している前提で書かれています

[LaravelでHTTPリクエストの単体テストを行う](https://qiita.com/toontoon/items/bb57147b616ec5a5038b)
本記事は上記が完了している前提で書かれています
上記記事で作成したクラスに追記していきます



# フォームリクエストの作成
 /sample/app/Http/Requests/Ut2Request.php作成

```Ut2Request.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class Ut2Request extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'aaaa' => ['max:5']
        ];
    }
}

```
aaaaというリクエストデータにmax:5の制限をかけただけの簡単なエラーチェックです

# Controllerにメソッド追加
(1) /sample/app/Http/Controllers/SampleController.phpに下記を追記
`use App\Http\Requests\Ut2Request;`

(2) /sample/app/Http/Controllers/SampleController.phpにut2メソッドを追記

```
    public function ut2(Ut2Request $request)
    {
        $data = [
            'input_aaaa'   => $request->input('aaaa'),
            'input_bbbb'   => $request->input('bbbb'),
            'session_abcd' => $request->getSession()->get("abcd")
        ];

        return $data;
    }
```

(3) /sample/routes/web.phpに下記を追記
`Route::post('sample/ut2', 'SampleController@ut2');`

# テストクラス修正
[LaravelでHTTPリクエストの単体テストを行う](https://qiita.com/toontoon/items/bb57147b616ec5a5038b)
上記記事で作成したSampleControllerTest.phpにメソッドを追加します
/sample/tests/Feature/SampleControllerTest.phpにtestUt2メソッド追記

```SampleControllerTest.php

    public function testUt2()
    {

        // エラーチェック処理テスト
        $response = $this->withSession(
                                      [
                                       'abcd' => 'a_session'
                                      ]
                           )
                         ->postJson('sample/ut2',
                                    [
                                        'aaaa' => '123456',
                                        'bbbb' => 'b_val'
                                    ]
                           );
        $response->assertJsonValidationErrors(['aaaa' => 'The aaaa may not be greater than 5 characters.']);
        $response->assertStatus(422);

        // 正常系テスト
        $response = $this->withSession(
                                      [
                                       'abcd' => 'a_session'
                                      ]
                           )
                         ->postJson('sample/ut2',
                                    [
                                        'aaaa' => 'a_val',
                                        'bbbb' => 'b_val'
                                    ]
                           );
         $response->assertJson(['input_aaaa' => 'a_val']);
         $response->assertJson(['input_bbbb' => 'b_val']);
         $response->assertJson(['session_abcd' => 'a_session']);

         $data = [
             'input_aaaa'   => 'a_val',
             'input_bbbb'   => 'b_val',
             'session_abcd' => 'a_session'
         ];
         $response->assertExactJson($data);

         $response->assertStatus(200);

    }
```

`$this->withSession`はセッションに値を格納します
`$this->withSession`の引数にセッションに格納する値を渡します
`$this->postJson`はPOSTでJSONリクエストを投げるということです
`$this->postJson`の引数にリクエストデータを渡します
GETリクエストのテストをしたい場合は`$this->getJson`にします

`$response->assertJsonValidationErrors`でエラーメッセージが出力されていることをテストできます
aaaaに対してmax:5のチェックをかけたので、6桁の値をpostリクエストするとエラーになるはずです
`$response->assertJson`でControllerの返した配列の中に、予測値が含まれているかをテストします
`$response->assertExactJson`Controllerの返した配列と予測値が完全に一致するかテストしています
他にもいろいろなassertメソッドが用意されています。下記リンクで確認できます
[Laravel 7.x HTTPテスト 利用可能なアサート](https://readouble.com/laravel/7.x/ja/http-tests.html#available-assertions)

# 動作確認
コマンドラインで
`cd sample`
`.\vendor\bin\phpunit tests/Feature/SampleControllerTest.php`
(windowsでない場合./vendor/bin/phpunit)

実行結果

```
PHPUnit 8.5.2 by Sebastian Bergmann and contributors.

..                                                                  2 / 2 (100%)

Time: 466 ms, Memory: 20.00 MB

OK (2 tests, 15 assertions)
```