2016-01-24 55 views
1

我是新的测试PHP与PHPSpec。我有一个类,我注入symfony当前记录的用户(TokenStorageInterface)。并对该用户进行更改。测试PHPSpec symfony登录用户

<?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); 
    } 
} 

而且已经写了规格为该类:

<?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()); 

调用未定义的方法预言\预言\ MethodProphecy ::的getUser()

回答

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); 
}