Search code examples
unit-testingqunit

Handling several event listeners


Update: here's a fiddle of my problem. The tests pass once, and fail the next time:

http://jsfiddle.net/samselikoff/hhk6u/4/

The problem is departments has events.on("userSet:company"), so both variables respond to the event.


This is a general question about unit testing. In my app, a certain event is fired, and several other pieces of my app listen for this event. I'd like to unit test each piece separately, since they are performing different functions; but to do this, I have to fire off the event in each test.

This causes problems, since the first test must fire off the event, triggering the listeners in the other tests. How can I keep my tests atomic while still testing multiple event listeners?

(I am using QUnit, but I think this is a more general unit-testing question).

Answer:

Jeferson is correct. One easy way to solve this, is to use events.once instead of events.on. This way you clean up your events from each test.


Solution

  • All your calls to async methods should be tested using "asyncTest" methods and making sure you wrap your calls in other functions that calls QUnit.start() when the assertions data are ready to be collected and analyzed.

    I updated your JSFiddle with working code: http://jsfiddle.net/hhk6u/8/ The new code is:

    QUnit.config.autostart = false;
    QUnit.config.testTimeOut = 1000;
    
    asyncTest('Some test that needs companies.', function() {
        function getCompanies() {
            var companies = new Companies();
            ok(1);
            start();
        }
        setTimeout(getCompanies, 500);
    });
    
    asyncTest('Some other async test that triggers a listener in companies.', function() {   
        var companies = new Companies();
    
        events.trigger("userSet:company", { name: "Acme", id: 1 });
    
        stop();
        events.on('fetched:departments', function(response) {
            console.log(response);
            deepEqual(response, [1, 2, 3]);
            start();
        });
    });
    

    See my answer in this other question for more details: Test fails then succeeds

    Hope this helps you!