Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write UnitTest for Symfony EventListener

I have a SymfonyBundle here, which is really not more then a custom EventDispatcher, and an EventListener.

How would I go about unit testing this code ?

I know how to create functional tests for controllers etc, but am not really sure how to go about writing tests for this dispatcher and listener..

Can someone point me in the right direction pls, google doesnt seem to help me out much on this one .

Thanks in advance.

Sam J

edit: 04/04/2014: This is the bundle im trying to create tests for

I already have tests set up to check if both services (dispatcher and listener) are loaded, but now i need to test the FUNCTIONALITY .. eg check if an event fired on MY dispatcher, is fired on the REAL dispatcher on kernel.terinate.

EDIT so i am bnasically assuming that i just need to fire my event, then somehow get to kernel.terminate, and check if my event was then fired by the real dispatcher, but how ..

like image 812
Sam Janssens Avatar asked Apr 03 '14 07:04

Sam Janssens


1 Answers

You can unit test your listener by mocking up all the necessary stuff it needs to work, for example, from a project of mine:

class UploadListenerTest extends \PHPUnit_Framework_TestCase
{
    public function testOnUpload()
    {
        $session = new Session(new MockArraySessionStorage());
        $file = new File(__FILE__);

        $event = new PostPersistEvent($file, new EmptyResponse, new Request(), "", []);

        $listener = new UploadListener($session);
        $listener->onUpload($event);

        $tempFiles = $session->get('_temp_files');

        $this->assertCount(1, $tempFiles);
        $this->assertEquals($tempFiles[0], $file->getFilename());

        $otherFile = new File(__FILE__);

        $event = new PostPersistEvent($otherFile, new EmptyResponse, new Request(), "", []);

        $listener->onUpload($event);

        $tempFiles = $session->get('_temp_files');

        $this->assertCount(2, $tempFiles);
        $this->assertEquals($tempFiles[0], $file->getFilename());
        $this->assertEquals($tempFiles[0], $otherFile->getFilename());
    }
} 

As you can see, I am creating every object my Event Listener needs in order to unit test it's behaviour.

You can also go the functional way. Boot the Symfony kernel and create the conditions for your event to trigger, and then test the expected conditions you need to have after the event is triggered:

public function testUploadNoFilesNoAjaxLoggedUser()
{
    $this->loginUser($this->getDummyUser());

    $response = $this->requestRoute(self::UPLOAD_ROUTE, "POST");

    $this->assertResponseRedirect("panel_index", $response);
}

As you can see, I'm first logging the user and then doing an actual request to the upload form. After that I assert that my response should be a redirection to the main panel. Symfony is triggering the event under the hood, and this event is returning the RedirectResponse I need to assert.

My recommendation is that you try to write both unit and functional tests, it will leave your application in a more stable state.

EDIT

Added answer to specific question on how to test an event dispatcher itself in this PR:

https://github.com/whitewhidow/AsyncDispatcherBundle/pull/1/files

like image 89
Alberto Fernández Avatar answered Nov 17 '22 01:11

Alberto Fernández