Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get UnitOfWork from EventManager Mock Object Or how to get last persisted object in PHP Unit?

I am trying to unit test my bundle and I want to get unit of work from EventManager Mock. Basically, I want to get the last persisted object. I know in normal application, I can do the same with a EventSubscriber.

What I want to achieve is basically, check status of previous persisted record if its flag is pending, then in next persist, I want to update it to not pending.

Example:

Here's how I get Event Manager:

/**
 * @param Entity\Friend|null $friendEntity
 * @return \Doctrine\ORM\EntityManager|\PHPUnit_Framework_MockObject_MockObject
 */
private function getEntityManager(Entity\Friend $friendEntity = null)
{
    $repository = $this
        ->getMockBuilder('\Doctrine\ORM\EntityRepository')
        ->disableOriginalConstructor()
        ->setMethods(['findBy'])
        ->getMock();
    $repository
        ->expects($this->any())
        ->method('findBy')
        ->will($this->returnValue(null));

    /** @var \Doctrine\ORM\EntityManager|\PHPUnit_Framework_MockObject_MockObject $entityManager */
    $entityManager = $this
        ->getMockBuilder('\Doctrine\ORM\EntityManager')
        ->setMethods(['getRepository', 'getUnitOfWork', 'persist'])
        ->disableOriginalConstructor()
        ->getMock();
    $entityManager
        ->expects($this->any())
        ->method('getRepository')
        ->will($this->returnValue($repository));
    $entityManager
        ->expects($this->any())
        ->method('getUnitOfWork')
        ->will($this->returnValue($repository));
    $entityManager
        ->expects($this->any())
        ->method('persist')
        ->with($friendEntity)
        ->will($this->returnValue(null));
    return $entityManager;
}

And in my test:

/**
 * Test add friend when friend pending
 */
public function testAddFriendPending()
{
    $friendEntity = new Entity\Friend($this->friend, $this->user);
    $entityManager = $this->getEntityManager($friendEntity);
    $pendingRequest = new FriendService($entityManager);
    /** @var Entity\Friend $lastInsert */
    $lastInsert = $pendingRequest->addFriend($this->friend, $this->user);
    $lastInsert->setId(1);
    $friendAddRequest = new FriendService($entityManager);
    $friendAddRequest->addFriend($this->user, $this->friend);
    $response = $friendAddRequest->getStatus();
    $this->assertEquals(Entity\Friend::FRIEND_ADD_STATUS_COMPLETED, $response);
}

EDIT

Still receiving errors:

vendor/phpunit/phpunit/phpunit src/NalabTnahsarp/FriendFollowerBundle/Tests/Service/
PHPUnit 5.7.21 by Sebastian Bergmann and contributors.

EE                                                                  2 / 2 (100%)

Time: 102 ms, Memory: 4.00MB

There were 2 errors:

1) NalabTnahsarp\FriendFollowerBundle\Tests\Service\FriendTest::testAddFriendNotPending
Error: Call to a member function getUnitOfWork() on null

/Users/Sites/app/vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php:194
/Users/Sites/app/src/NalabTnahsarp/FriendFollowerBundle/Service/Friend.php:140
/Users/Sites/app/src/NalabTnahsarp/FriendFollowerBundle/Service/Friend.php:63
/Users/Sites/app/src/NalabTnahsarp/FriendFollowerBundle/Tests/Service/FriendTest.php:43

2) NalabTnahsarp\FriendFollowerBundle\Tests\Service\FriendTest::testAddFriendPending
Error: Call to a member function getUnitOfWork() on null

/Users/Sites/app/vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php:194
/Users/Sites/app/src/NalabTnahsarp/FriendFollowerBundle/Service/Friend.php:140
/Users/Sites/app/src/NalabTnahsarp/FriendFollowerBundle/Service/Friend.php:63
/Users/Sites/app/src/NalabTnahsarp/FriendFollowerBundle/Tests/Service/FriendTest.php:57
like image 346
Gaurav Avatar asked Jun 27 '17 14:06

Gaurav


1 Answers

I suppose you want to check that the persisted entity has some specific values set and of course is the right type.

You should add this to the persist method for the entity manager like this:

If persist() is only called once you have it easy:

$entityManager
    ->expects($this->once())
    ->method('persist')
    ->with($theEntityYouExpectWithAllValues)
    ->will($this->returnValue(null));

With more sophisticated expectations:

$entityManager
    ->expects($this->once())
    ->method('persist')
    ->willReturnCallback(function($entityToTest){
        $this->assertInstanceOf(EntityClass::class, $entityToTest);
        $this->assertEquals('some_value', $entityToTest->someKey);
    });

If it is not the only call to persist() in the tested code you have to use $this->at() instead of once():

$entityManager
    ->expects($this->at(3)) // 3rd call of any method on manager not just persist
    ->method('persist')
    // ...
like image 145
colburton Avatar answered Nov 15 '22 00:11

colburton