How to test JavaScript Event Handlers
22 February 2013
At some point, you'll find event handling code on top of jQuery written like this:
$('#some-element').click(function(e) {e.preventDefault();$(this).toggleClass('active');});
Testing this code will require us to:
- Setup a HTML fixture so that the event can bind to it.
- Fire the actual click event on the fixture
- Assert if the CSS class was changed on the target element
Here's the test:
// Create fixture$('body').append('<div id="#some-element"></div>');// Trigger click event$('#some-element').trigger('click');// Assertassert($('some-element').attr('class') == 'active');
We're essentially forced to test our code through the jQuery API. As you may know, jQuery already has a test suite, we should really focus on testing our code.
Further more, there is no way to assert that e.preventDefault()
was called.
Let's make our code slightly more verbose to improve testability.
$('#some-element').click(toggleMe);function toggleMe(e) {e.preventDefault();$(e.target).toggleClass('active');}
Testing the above will be easier:
// Setupvar div = document.createElement('div');var e = {target : div,preventDefault: sinon.spy()}toggleMe(e);//Assertassert(e.preventDefault.called);assert(div.className == 'active');
The sinon.spy()
method is from Sinon.js which is an excellent library for performing common test tasks like spying and stubbing. It allows us to assert that the preventDefault was called on the supplied event object.
That's all folks. Happy refactoring!