laravel DataProviderを用いてテストを短く記載する

# 概要

- DataProviderを用いてテストを短く記載する方法をまとめる。

# 方法

1. 下記の様なテストコードのクラスがあったとする。

    ```FooTest.php
    public function test_正常系_01()
    {
        CarbonImmutable::setTestNow();
        $fooService = resolve(FooService::class);
        $int_1 = 1;
        $str_1 = 'test';
    
        $fooService->create($int_1, $str_1);
    
        $this->assertDatabaseHas(
            'tests',
            [
                'int1' => $int_1,
                'str1' => $str_1,
            ]
        );
    }
    
    public function test_正常系_02()
    {
        CarbonImmutable::setTestNow();
        $fooService = resolve(FooService::class);
        $int_1 = 0;
        $str_1 = 'test';
    
        $fooService->create($int_1, $str_1);
    
        $this->assertDatabaseHas(
            'tests',
            [
                'int1' => $int_1,
                'str1' => $str_1,
            ]
        );
    }
    
    public function test_異常系_01()
    {
        CarbonImmutable::setTestNow();
        $fooService = resolve(FooService::class);
        $int_1 = null;
        $str_1 = 'test';
    
        $fooService->create($int_1, $str_1);
        
        $this->expectException(\TypeError::class);
    }
    
    public function test_異常系_02()
    {
        CarbonImmutable::setTestNow();
        $fooService = resolve(FooService::class);
        $int_1 = 1;
        $str_1 = null;
    
        $fooService->create($int_1, $str_1);
    
        $this->expectException(\TypeError::class);
    }
    ```

1. 上記4種類のテストメソッドはそれぞれ正常系は正常系で異常系は異常系でパラメーターが異なっているだけで同じ内容をチェックしている。
1. 下記の様にDataProviderを使うことでテストを短縮して記載する事ができる。

    ```FooTest.php
    /**
     * @dataProvider dataProvider
     */
    public function test_正常系(int $int_1, string $str_1)
    {
        CarbonImmutable::setTestNow();
        $fooService = resolve(FooService::class);
    
        $fooService->create($int_1, $str_1);
    
        $this->assertDatabaseHas(
            'tests',
            [
                'int1' => $int_1,
                'str1' => $str_1,
            ]
        );
    }
    
    /**
     * 正常系用dataProvider
     * 
     * @return array
     */
    public function dataProvider(): array
    {
        return [
            [1, 'test'],
            [0, 'test'],
        ];
    }
    
    /**
     * @dataProvider dataProviderForError
     */
    public function test_異常系($int_1, $str_1)
    {
        CarbonImmutable::setTestNow();
        $fooService = resolve(FooService::class);
    
        $fooService->create($int_1, $str_1);
        
        $this->expectException(\TypeError::class);
    }
    
    /**
     * 異常系用dataProvider
     * 
     * @return array
     */
    public function dataProviderForError(): array
    {
        return [
            [null, 'test'],
            [1, null],
        ];
    }
    ```

1. 下記の様に記載する事もできる。

    ```FooTest.php
    /**
     * @dataProvider dataProvider
     */
    public function test_正常系(int $int_1, string $str_1)
    {
        CarbonImmutable::setTestNow();
        $fooService = resolve(FooService::class);
    
        $fooService->create($int_1, $str_1);
    
        $this->assertDatabaseHas(
            'tests',
            [
                'int1' => $int_1,
                'str1' => $str_1,
            ]
        );
    }
    
    /**
     * 正常系用dataProvider
     * 
     * @return array
     */
    public function dataProvider(): array
    {
        return [
            'int1が1' => [1, 'test'],
            'int1が0' => [0, 'test'],
        ];
    }
    
    /**
     * @dataProvider dataProviderForError
     */
    public function test_異常系($int_1, $str_1)
    {
        CarbonImmutable::setTestNow();
        $fooService = resolve(FooService::class);
    
        $fooService->create($int_1, $str_1);
        
        $this->expectException(\TypeError::class);
    }
    
    /**
     * 異常系用dataProvider
     * 
     * @return array
     */
    public function dataProviderForError(): array
    {
        return [
            'int1がnull' => [null, 'test'],
            'str1がnull' => [1, null],
        ];
    }
    ```