mercredi 18 novembre 2015

Symfony2 - PHPunit - test method on event subscriber is called

Below is a event subscriber for a 'Test' entity. I have code that assigns a contract and an email needs to be sent when this happens. The code below will send the email. My problem is righting a test that makes sure the method 'sendContractAssignedEmail' was run if the contract property of the test entity is changed from null

class TestEventSubscriber implements EventSubscriber
{
    function __construct(Container $container)
    {
        $this->container = $container        
    }

    function getSubscribedEvents()
    {
        return array(
            Events::postUpdate,
        );
    }

    public function postUpdate(LifecycleEventArgs $args)
    {

    $entity = $args->getEntity();
    $changeSet = $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet( $entity);

    if ($entity instanceof Test && isset($changeSet['contract']) && empty($changeSet['contract'][0]))
        $this->sendContractAssignedEmail($lead);

    }

    private function sendContractAssignedEmail(Test $test)
    {
        //irrelevant code to send email 
    }

}

I have a function that assigns a contract on the testHandler

public function assign(Test $test, Contract $contract) {

    if (is_null($test->getContract())) {
        $test->setContract($contract);
    }

    return $test;
}

this is called from the testController and does trigger the postUpdate event and also does send the email. Im just really struggling on how to test this using PHPunit? I have read a lot but none of it seems to suit what i need. I looked into mocking but Im not sure i understand it correctly

public function testEmailSentOnAssignTest() 
    $test = $this->testRepo->getOne(1);
    $objectManager = $this->getObjectManager();

    $mock = $this->getMockBuilder('SoapMedia\LeadZenBundle\EventSubscriber\LeadEventsSubscriber')
            ->disableOriginalConstructor()
            ->setMethods(array('sendContractAssignedEmail'))
            ->getMock();

    $args = new LifecycleEventArgs($lead, $objectManager);
    $mock->expects($this->once())->method('sendContractAssignedEmail');
    $mock->postUpdate($args);

}

I understand why the above doesn't work i think. The post update function looks for changes to the contract property and there isn't one so the email function is never run. Can i fake the EntityChangeSet somehow or what is the best way to test this event? I'm very new to unit testing so excuse me if I'm miles off!

Aucun commentaire:

Enregistrer un commentaire