TotT: Simulating Time in jsUnit Tests
For example, this function will set up some callbacks to update a status message over the course of four seconds:
function showProgress(status) {
status.message = "Loading";
for (var time = 1000; time <= 3000; time+= 1000) {
// Append a '.' to the message every second for 3 secs.
setTimeout(function() {
status.message += ".";
}, time);
}
setTimeout(function() {
// Special case for the 4th second.
status.message = "Done";
}, 4000);
}
The jsUnit test for this function would look like this:
function testUpdatesStatusMessageOverFourSeconds() {
Clock.reset(); // Clear any existing timeout functions on the event queue.
var status = {};
showProgress(status); // Call our function.
assertEquals("Loading", status.message);
Clock.tick(2000); // Call any functions on the event queue that have been
// scheduled for the first two seconds.
assertEquals("Loading..", status.message);
Clock.tick(2000); // Same thing again, for the next two seconds.
assertEquals("Done", status.message);
}
This test will run very quickly - it does not require four seconds to run.
Clock supports the functions setTimeout(), setInterval(), clearTimeout(), and clearInterval(). The Clock object is defined in jsUnitMockTimeout.js, which is in the same directory as jsUnitCore.js.
I've been thinking about this in the context of doctest.js (though not actually doing anything about it), and while this would solve part of the problem sometimes you really need to let go of the interpreter, particularly when dealing with the DOM. For this reason I think generally a function-that-does-stuff is a bad way to setup a JS test. In the case of doctest.js I think it would be possible (with lots of refactoring) to actually solve this fairly transparently in the test framework, but deconstructing the functions in jsUnit doesn't seem possible.
ReplyDeleteIsn't this the same TotT from March 29, 2007? I have it printed out in my cubical and it sure looks the same. I'm not complaining, but perhaps a "TotT Classic" title would be more appropriate?
ReplyDelete