jQuery: Approaches to testing
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.
[...] jQuery: Approaches to Testing (Mark Needham) [...]
Dew Drop - Weekend Edition - January 24-25, 2009 | Alvin Ashcraft's Morning Dew
25 Jan 09 at 1:03 pm
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?
Elijah Manor
4 Jan 10 at 4:59 am
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
Elijah Manor
4 Jan 10 at 6:21 am
Consider using Jasmine: http://github.com/pivotal/jasmine
It's pretty much replaced screw.unit.
Andrew
25 Feb 10 at 12:20 am