Laravelのバリデーションでテスト時のみ項目を除外する

2024.09.17 09:00
2024.09.12 13:48
Laravelのバリデーションでテスト時のみ項目を除外する

今回はLaravelでフォーム検証のGoogle reCAPTCHAを使うときの話です。
Featureテスト時にreCAPTCHAのトークンがとれないのでバリデーションを除外してみました。
reCAPTCHAテストの対応としてあっているかはわかりませんが(多分望ましい方法ではなさそうな気はする)、とりあえず無事動いていますのでやむなしとします。

対策としては、バリデーション時に環境変数をよんで、「testing」なら「g-recaptcha-response」を外すようにしました。

まずは通常のパターン。

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'contact.name' => 'required|string|max:255',
            'contact.kana' => 'present|string',
            'contact.email' => 'required|email|string',
            'contact.tel' => 'present|string',
            'contact.reply' => 'required|string',
            'contact.msg' => 'required|string',
            'contact.privacy' => 'required|numeric|between:0,1',
            'g-recaptcha-response' => 'required|recaptchav3:contact,0.5'
        ];
    }

普通に使う分にはなんら問題ないのですが、これだとコントローラーのテスト時にトークンをセットすることができずに、バリデーションで引っかかってテストが通りません。

続いて対策した方のパターン。

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        // 値をセット
        $rules = [
            'contact.name' => 'required|string|max:255',
            'contact.kana' => 'present|string',
            'contact.email' => 'required|email|string',
            'contact.tel' => 'present|string',
            'contact.reply' => 'required|string',
            'contact.msg' => 'required|string',
            'contact.privacy' => 'required|numeric|between:0,1',
            'g-recaptcha-response' => 'required|recaptchav3:contact,0.5'
        ];

        // テストの場合だけreCAPTCHAを外す
        if(config('app.env') === 'testing') unset($rules['g-recaptcha-response']);

        // 値を返す
        return $rules;
    }

先に全てのバリデーションを配列変数に入れてから、
条件判断でreCAPTCHA用のバリデーションを外すようにしてあります。

これで通常とテストの両方に対応できるようになりました。
無理やり感があって正しいかはわかりませんが、
他の方法を見つけられなかったのでしょうがありません。

今回は以上です!