Mark Needham

Thoughts on Software Development

jQuery: Approaches to testing

with 4 comments

We’ve been doing a bit of work with jQuery and true to our TDD roots we’ve been trying to work out the best way to test drive our coding in this area.

There seem to be 3 main ways that you can go about doing this, regardless of the testing framework you choose to you. We are using screw-unit for our javascript testing.

Mock everything out

The idea here is that we mock out all calls made to jQuery functions and then we assert that the expected calls were made in our test.

Taking this approach means we are able to reduce the dependencies in our tests and they run very quickly.

The problem is that a lot of assertions become assertions checking that certain operations were called on the DOM since jQuery makes a lot of these type of calls in its code. The tests therefore end up being quite long and difficult to understand unless you were the one who initially wrote them.

We also effectively end up testing how the framework interacts with the DOM rather than testing our own code with this approach.

Don’t mock anything

The opposite approach is to just test directly against jQuery and then do assertions against the part of the DOM affected by the javascript code we are testing.

The problem here is that if you want to test against plugins which make ajax requests or carry out animation effects then the tests become dependent on how long these calls take and we need to find a way to block the test until those calls return which is quite difficult!

Only stub certain calls

The happy medium is that we test directly against the jQuery library but stub out ajax requests and animation effects. Our test assertions are against the state of the DOM to check that it was changed in the way that we expected.

This approach allows us to test our javascript code in terms of its behaviour without testing the internals of how jQuery works.

The wiring up of events to different controls on the page is done in our test but the actual logic that happens when these events are fired is in our js file under test.

We currently favour this last approach as it seems to give us the best of both worlds so to speak. It be would be interesting to hear how are other people going about Javascript testing.

Be Sociable, Share!

Written by Mark Needham

January 24th, 2009 at 9:36 am

Posted in jQuery

Tagged with

  • Pingback: Dew Drop - Weekend Edition - January 24-25, 2009 | Alvin Ashcraft's Morning Dew()

  • I know this is almost a year after you posted this, but I’d be interested to see how you are stubbing out the AJAX request w/ jQuery. I imagine you are stubbing out the return success callback with a static value so that the actual HTTP request isn’t being made, correct? Do you have a sample out there somewhere?

  • Ahh.. I modified the source code of qmock to suite my needs 😉

    Now I can do something like…

    var mock$ = new Mock();
    mock$
    .expects(1)
    .method(‘ajax’)
    .withArguments({
    url: String,
    success: Function,
    dataType: “jsonp”
    })
    .callFunctionWith(‘data response’);

    and then I pass mock$ into my function as a variable that acts like the jQuery object

  • Andrew

    Consider using Jasmine: http://github.com/pivotal/jasmine

    It’s pretty much replaced screw.unit.