PHPUnit の備忘録

zumikiti

September 15, 2022

以下のクラスのテストのテストを書いていきます。

<?php

namespace  App\Actions\Item;

use App\Models\Item;

class CreateItem
{
    private $cdType = 'TY';

    public function execute(array $input)
    {
        if ($this->isUniqueItemName($input)) {
            return abort(422);
        }

        return Item::create([
            ...$input,
            'item_cd' => $this->generateItemCd(mt_rand()),
        ]);
    }

    public function isUniqueItemName($input)
    {
        $itemName = $input['item_name'];

        return !Item::whereItemName($itemName)->exists();
    }

    private function generateItemCd($number)
    {
        return $this->cdType . $number;
    }
}

モックを使用する

<?php

namespace Tests\UnitActions\Item;

use App\Actions\Item\CreateItem;
use App\Models\Item;
use ReflectionClass;
use Tests\TestCaseWithDb;

class CreateItemTest extends TestCaseWithDb
{
    /**
     * @testWith [true, false]
     */
    public function testCreate(bool $bool)
    {
       $input = Item::factory()->make()->toArray();

       $mock = $this->getMockBuilder(CreateItem::class)
                    ->setMethods(['isUniqueItemName'])
                    ->getMock();
       $mock->expects($this->once())
            ->method('isUniqueItemName')
            ->willReturn($bool);

       try {
           $result = $mock->execute($input);
           $this->assertDatabaseHas('items', $input);
       } catch (\Exception $e) {
           $this->assertTrue($e instanceof \Symfony\Component\HttpKernel\Exception\HttpException);
       }
    }
}

private protected なプロパティやメソッドのテスト

<?php

namespace Tests\UnitActions\Item;

use App\Actions\Item\CreateItem;
use App\Models\Item;
use ReflectionClass;
use Tests\TestCaseWithDb;

class CreateItemTest extends TestCaseWithDb
{
    public function testGenerateItemCd()
    {
        $create = new CreateItem();

        $reflection = new ReflectionClass($create);
        $generateItemCd = $reflection->getMethod('generateItemCd');
        $generateItemCd->setAccessible(true);
        $cdType = $reflection->getProperty('cdType');
        $cdType->setAccessible(true);

        $num = mt_rand();
        $expected = $cdType->getValue($create) . $num;
        $result = $generateItemCd->invoke($create, $num);
        $this->assertSame($expected, $result);
    }
}