我是使用PHPSpec测试PHP的新手。我有一个类,我注入symfony当前记录的用户(TokenStorageInterface)。并对该用户进行更改。
<?php
namespace AppBundle\Service;
use AppBundle\Entity\Payment;
use AppBundle\Entity\User;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class TransferService
{
/**
* @var EntityManager
*/
private $entityManager;
/**
* @var TokenStorageInterface
*/
private $tokenStorage;
/**
* @var User
*/
private $currentUser;
/**
* @var InvoiceService
*/
private $invoiceService;
/**
* PaymentManager constructor.
* @param EntityManager $entityManager
* @param TokenStorageInterface $tokenStorage
* @param InvoiceService $invoiceService
*/
public function __construct(
EntityManager $entityManager,
TokenStorageInterface $tokenStorage,
InvoiceService $invoiceService
) {
$this->entityManager = $entityManager;
if ($tokenStorage->getToken() === null) {
throw new \Exception('User not logged in');
}
$this->currentUser = $tokenStorage->getToken()->getUser();
$this->invoiceService = $invoiceService;
}
/**
* @param Payment $payment
*/
public function transfer(Payment $payment)
{
$payer = $this->currentUser;
$amount = $payment->getAmount();
$receiver = $payment->getReceiver();
if ($payer === $receiver) {
throw new \LogicException('Cannot be same User');
}
if ($payer->getBalance() < $amount) {
throw new \LogicException('Not enough in balance');
}
$payment->setPayer($payer);
//TODO: Move to class?
$this->subtractBalance($payer, $amount);
$this->addBalance($receiver, $amount);
$this->invoiceService->createInvoice($payment);
$this->entityManager->persist($payment);
$this->entityManager->flush();
}
/**
* @param User $user
* @param $amount
*/
private function subtractBalance(User $user, $amount)
{
$user->setBalance($user->getBalance() - $amount);
}
/**
* @param User $user
* @param $amount
*/
private function addBalance(User $user, $amount)
{
$temp = $user->getBalance();
$user->setBalance($user->getBalance() + $amount);
}
}
并为该课程编写了Spec:
<?php
namespace spec\AppBundle\Service;
use AppBundle\Entity\Payment;
use AppBundle\Entity\User;
use AppBundle\Service\InvoiceService;
use Doctrine\ORM\EntityManager;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
class TransferServiceSpec extends ObjectBehavior
{
function let(EntityManager $entityManager, TokenStorage $tokenStorage, InvoiceService $invoiceService)
{
$user = new User();
$user->setUsername('aaa');
$user->setBalance(100.10);
$temp = new UsernamePasswordToken($user, null, 'main', ['ROLE_USER']);
$tokenStorage->getToken()->willReturn($temp);
$this->beConstructedWith($entityManager, $tokenStorage, $invoiceService);
}
function it_is_initializable()
{
$this->shouldHaveType('AppBundle\Service\TransferService');
}
function it_should_transfer_money(
User $user,
EntityManager $entityManager,
TokenStorageInterface $tokenStorage,
InvoiceService $invoiceService,
Payment $payment
) {
$user->getBalance()->willReturn(0);
$user->setBalance(99.9)->shouldBeCalled();
$payment->getReceiver()->willReturn($user);
//TODO how to check injected current user?
//$payment->getPayer()->willReturn($tokenStorage->getToken());
$payment->getAmount()->willReturn(99.9);
$invoiceService->createInvoice($payment)->shouldBeCalled();
$entityManager->persist($payment)->shouldBeCalled();
$entityManager->flush()->shouldBeCalled();
$this->transfer($payment);
}
}
问题是,如何检查当前用户(注入令牌存储器getUser())是否进行了更改(以测试该天平已编辑),因为以下方法不起作用:
$payment->getPayer()->willReturn($tokenStorage->getToken()->getUser());
调用未定义的方法Prophecy \ Prophecy \ MethodProphecy :: getUser()
答案 0 :(得分:2)
你不应该在预言中调用方法,而是模仿一切,参见:
function it_should_transfer_money(
User $user,
EntityManager $entityManager,
TokenStorageInterface $tokenStorage,
TokenInterface $token,
UserInterface $user,
InvoiceService $invoiceService,
Payment $payment
) {
$user->getBalance()->willReturn(0);
$user->setBalance(99.9)->shouldBeCalled();
$payment->getReceiver()->willReturn($user);
$tokenStorage->getToken()->willReturn($token);
$token->getUser()->willReturn($user);
$payment->getPayer()->willReturn($user);
$payment->getAmount()->willReturn(99.9);
$invoiceService->createInvoice($payment)->shouldBeCalled();
$entityManager->persist($payment)->shouldBeCalled();
$entityManager->flush()->shouldBeCalled();
$this->transfer($payment);
}