我有一个界面,如下所示:
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());
但返回
TypeError:Double\UserRepository\P1::Save()的返回值必须是app\domain\user\User的实例,返回null
我使用了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();