LaravelのサービスコンテナをモックしてUnitテストする

Laravelのモデルやコントローラーが肥大化し始めたのでサービスコンテナに処理を移行し始めました。

サービスコンテナの利点はテストがしやすくなる実装方法なのですが、公式ドキュメントにドンズバのサンプルがなかったので一応残しておきます。

サンプルのサービスクラス

<?php

namespace App\Services;

use App\Repositories\UserRepository;

class CreateUserService
{
    public function __construct(
        protected UserRepository $userRepository
    ) {
    }

    public function handle(string $name): bool
    {
        return $this->userRepository->create($name);
    }
}

テストコード

<?php

namespace Tests\Unit\Services;

use App\Repositories\UserRepository;
use App\Services\CreateUserService;
use Mockery\MockInterface;
use Tests\TestCase;

class CreateUserServiceTest extends TestCase
{

    /**
     * @test
     */
    public function 成功_ユーザー作成()
    {
        $userRepository = $this->mock(UserRepository::class, function (MockInterface $mock) {
            $mock->shouldReceive('create')->with('user name')->once()->andReturn(true);
        });

        $this->instance(UserRepository::class, $userRepository);
        $service = app()->make(CreateUserService::class);
        $status = $service->handle('user name');
        $this->assertSame($status, true);
    }
}

こちらでUserRepositoryのクラスをモックした状態で引き渡されます。

以下の記述でモックしたクラスがインスタンス化され

$this->instance(UserRepository::class, $userRepository);

以下の記述でモックが注入された状態で初期化されます。

$service = app()->make(CreateUserService::class);

参照

https://laravel.com/docs/10.x/container

https://laravel.com/docs/10.x/mocking

PHPUnitの初期設定はこちらを参照ください。

投稿者


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA