yusuke921's blog

労働はオワコン

【Laravel】dataProviderを使って単体テストの境界値テストをスマートに書く

はじめに

この記事はLaravel Advent Calendar 2018 - Qiitaの13日目の記事です。

qiita.com

昨日は@nyamucoroさんの記事で 「初心者も出来た!Laravelの中身を読んでコントリビュートしよう 」でした!

今回はdataProviderを使って単体テストの境界値テストをスマートに書いてみます。

テスト対象クラス

<?php

namespace App\Services;

class FizzBuzzService
{
    public function fizzBuzz($num)
    {
        if ( ($num % 15) === 0 ) {
            return 'FizzBuzz';
        } elseif ( ($num % 3) === 0 ) {
            return 'Fizz';
        } elseif ( ($num % 5) === 0 ) {
            return 'Buzz';
        } else {
            return $num;
        }
    }
}

有名なあれです

愚直にテストクラスを書いてみる

<?php

namespace Tests\Unit\App\Services;

use App\Services\FizzBuzzService;
use Tests\TestCase;

class FizzBuzzServiceTest extends TestCase
{
    public function testFizzBuzz_3でも5でも割り切れる場合()
    {
        $fizz_buzz_service = new FizzBuzzService();
        $num = 15;
        $actual = $fizz_buzz_service->fizzBuzz($num);
        $expected = 'FizzBuzz';

        $this->assertEquals($expected, $actual);
    }

    public function testFizzBuzz_3で割り切れる場合()
    {
        $fizz_buzz_service = new FizzBuzzService();
        $num = 3;
        $actual = $fizz_buzz_service->fizzBuzz($num);
        $expected = 'Fizz';

        $this->assertEquals($expected, $actual);
    }

    public function testFizzBuzz_5で割り切れる場合()
    {
        $fizz_buzz_service = new FizzBuzzService();
        $num = 5;
        $actual = $fizz_buzz_service->fizzBuzz($num);
        $expected = 'Buzz';

        $this->assertEquals($expected, $actual);
    }

    public function testFizzBuzz_3でも5でも割り切れない場合()
    {
        $fizz_buzz_service = new FizzBuzzService();
        $num = 11;
        $actual = $fizz_buzz_service->fizzBuzz($num);
        $expected = 11;

        $this->assertEquals($expected, $actual);
    }
}

dataProviderを使ってスマートに書く

<?php

namespace Tests\Unit\App\Services;

use App\Services\FizzBuzzService;
use Tests\TestCase;

class FizzBuzzServiceTest extends TestCase
{
    /**
     * @dataProvider testData
     */
    public function testFizzBuzz($expected, $num)
    {
        $fizz_buzz_service = new FizzBuzzService();
        $actual = $fizz_buzz_service->fizzBuzz($num);

        $this->assertEquals($expected, $actual);
    }

    public function testData()
    {
        return [
            '3でも5でも割り切れる場合'   => ['FizzBuzz', 15],
            '3で割り切れる場合'         => ['Fizz', 3],
            '5で割り切れる場合'         => ['Buzz', 5],
            '3でも5でも割り切れない場合' => [11, 11],
        ];
    }
}

だいぶスッキリしたと思います。

テスト対象のメソッドの実装によってはdataProviderがバシッとハマらないケースも多々ありますが 今回のような境界値の振る舞いをテストしたい場合にはオススメなので使ってみてください。

明日は@kkznchさんの記事で 「LaravelのPivotモデルを使い中間テーブルから関係を取得する」です!