在 PHPUnit 中模拟接口时出现 TypeError
Getting TypeError when mocking interface in PHPUnit
我的界面如下:
interface UserRepository
{
public function save(User $user): User;
}
我需要为此功能编写单元测试
public function action()
{
$data = $this->request->getParsedBody() ?? [];
$user = new User($data);
$this->userRepository->save($user);
}
我尝试模拟用户存储库界面
$app = $this->getAppInstance();
$container = $app->getContainer();
$user = new User(['a' => 'b']);
$userRepositoryProphecy = $this->prophesize(UserRepository::class);
$userRepositoryProphecy
->save($user)
->willReturn($user)
->shouldBeCalledOnce();
$container->set(UserRepository::class, $userRepositoryProphecy->reveal());
但是return
TypeError : Return value of Double\UserRepository\P1::save() must be an instance of App\Domain\User\User, null returned
我使用了 slim-skeleton 和 phpunit
您的测试用例丢失,但我猜您在测试中保存的用户与您用来设置模拟的用户不同。澄清一下:
$userA = new User(['a' => 'b']);
$userB = new User(['c' => 'd']);
$prophecy = $this->prophesize(UserRepository::class);
$prophecy->save($userA)
->willReturn($userA)
->shouldBeCalledOnce();
$repo = $prophecy->reveal();
$repo->save($userA); // returns $userA
$repo->save($userB); // returns null
如果您的用户存在您无法控制且不想摆脱的副作用,您可以使用回调来检查给定用户是否是您要查找的用户。
$prophecy->save(Argument::that(fn(User $user) => $user->data === ['a' => 'b']))
->willReturnArgument()
->shouldBeCalledOnce();
我的界面如下:
interface UserRepository
{
public function save(User $user): User;
}
我需要为此功能编写单元测试
public function action()
{
$data = $this->request->getParsedBody() ?? [];
$user = new User($data);
$this->userRepository->save($user);
}
我尝试模拟用户存储库界面
$app = $this->getAppInstance();
$container = $app->getContainer();
$user = new User(['a' => 'b']);
$userRepositoryProphecy = $this->prophesize(UserRepository::class);
$userRepositoryProphecy
->save($user)
->willReturn($user)
->shouldBeCalledOnce();
$container->set(UserRepository::class, $userRepositoryProphecy->reveal());
但是return
TypeError : Return value of Double\UserRepository\P1::save() must be an instance of App\Domain\User\User, null returned
我使用了 slim-skeleton 和 phpunit
您的测试用例丢失,但我猜您在测试中保存的用户与您用来设置模拟的用户不同。澄清一下:
$userA = new User(['a' => 'b']);
$userB = new User(['c' => 'd']);
$prophecy = $this->prophesize(UserRepository::class);
$prophecy->save($userA)
->willReturn($userA)
->shouldBeCalledOnce();
$repo = $prophecy->reveal();
$repo->save($userA); // returns $userA
$repo->save($userB); // returns null
如果您的用户存在您无法控制且不想摆脱的副作用,您可以使用回调来检查给定用户是否是您要查找的用户。
$prophecy->save(Argument::that(fn(User $user) => $user->data === ['a' => 'b']))
->willReturnArgument()
->shouldBeCalledOnce();