class DeleteUserServiceTest extends TestCase { /** * 退会処理時にユーザーのEmail情報が無効化がされること * * @return void */ public function test_handle_退会処理時にユーザー削除処理のテスト() { // [A] 期待値の用意 // (何が必要か?) DeleteUserServiceを見て決める // (1) $userLeave // => [Factory] UserActive, UserDetail, UserDocument // => [new] UserActive, UserDetail, UserDocument // 今回は、Factoryのバターンに類似 $user = User::factory()->make(); $userLeave = UserLeave::factory()->make(); $userLeave->user = $user; // [B] UserRepositoryはMockを利用する // (UserRepository内のどのメソッドの呼び出しを許可するのか?) // // DeleteUserServiceクラスのhandleメソッド内において、 // UserRepository (親Models/User)のクラスが呼ばれているのは // (1) revokeEmailDomain // => UserRepository (親Models/User)のrevokeEmailDomainメソッドが返すのは // => (@return App\Model\User) // (2) update (@return App\Models\User) // (3) delete (@return void) $mock = $this->mock(UserRepository::class, function (MockInterface $mock) use ($user) { $mock->shouldReceive('update')->andReturn($user); $mock->shouldReceive('delete'); }); // [C] 実測値としてServiceクラスのインスタンスを生成 (handleメソッドの実行) $service = app()->make(DeleteUserService::class); // [D] DeleteUserInput はテスト用の具象クラスを用意(無名クラスで良い) $service->handle($this->createMockUserDeleteInput($user)); // [E] 正常系の確認 // (1) $this->userRepository->update($user) が呼び出されたことをテスト // (2) $this->userRepository->delete($user) が呼び出されたことをテスト $mock->shouldHaveReceived('update'); $mock->shouldHaveReceived('delete'); } /** * Mock用のDeleteUserInputを作成 * * @param User $user * @return DeleteUserInput */ private function createMockDeleteUserInput(User $user): DeleteUserInput { return new class($user) implements DeleteUserInput { private User $user; public function __construct(User $user) { $this->user = $user; } public function model(): User { return $this->user; } }; } }