Closed1

laravel8¦FormRequestでsometimesを使用する - withValidatorのunitテストもする

fuwakanifuwakani

やりたいこと

2つの入力フィールドa,bがあった時 bが入力されていた場合はaと異なる値であることを確認したい
テストもできるようにする

具体例

メールの送信先を設定する画面を想定

  • toはひとつだけ
  • ccが入力されていた場合はtoと異なるアドレスである

環境

  • laravel 8
  • php 7.3

FormRequest

sometimesを使いたいが、なぜかFormRequestではsometimesがruleに設定できない様子。なぜ( ´~` )

なのでValidatorインスタンスでsometimesを使用する必要がある
テストのしやすさを考えてwithValidator内でsometimesを使用する

TestRequest.php
public function rules()
{
    return [
        'to' => 'required|array|size:1',
        'to.*' => 'required',
    ];
}

public function withValidator(\Illuminate\Validation\Validator $validator) : void
{
    $validator->after(function ($validator) {
        $params = $this->all();
        if (isset($params['cc'])) {
            foreach ($params['cc'] as $cc) {
                if ($params['to'][0] === $cc) {
                    $validator->errors()
                        ->add('cc_error', \TestConst::TYPE[\TestConst::CC] . 'は' .\TestConst::TYPE[\TestConst::TO] .'と同一にできません。');
                }
            }
        }
    });
}

public function attributes()
{
    return [
        'to' => \TestConst::TYPE[\TestConst::TO],
        'to.*' => \TestConst::TYPE[\TestConst::TO],
    ];
}

配列チェックする場合toto.*の両方ないと上手くいかない( ´~` )

test

普通にテストするとwithValidatorはテストされないので注意

TestRequestTest
public function setUp() : void
{
    parent::setUp();
}

/**
 * @test
 */
public function testSuccessValidation()
{
    $params = $this->prepareSuccessParams();
    foreach ($params as $param) {
        $this->assertTrue($this->executeRequest($param));
    }
}

/**
 * @test
 */
public function testFieldValidation()
{
    $params = $this->prepareFailedParams();
    foreach ($params as $param) {
        $this->assertFalse($this->executeRequest($param));
    }
}

protected function executeRequest(array $param) : bool
{
    $this->app->resolving(TestRequest::class, function ($resolved) use ($param) {
        $resolved->merge($param);
    });

    try {
        app(TestRequest::class);
        return true;
    } catch (\Exception $e) {
        return false;
    }
}

private function prepareSuccessParams() : array
{
    return [
        [
            'to' => [1]
        ],[
            'to' => [1],
            'cc' => [2]
        ],[
            'to' => [1],
            'cc' => [2, 3]
        ],
    ];
}

private function prepareFailedParams() : array
{
    return [
        [
            'to' => 1
        ],[
            'to' => [1, 2]
        ],[
            'to' => [1],
            'cc' => [1]
        ]
    ];
}
このスクラップは2021/10/25にクローズされました