pivotal/jasmine — Issue #178: API Suggestion: Use an explicit callback argument for completion of async specs
Author: Squeegy
Created: 2012-01-16 23:03:13+00:00
State: open

Reading through the mocha.js docs: http://visionmedia.github.com/mocha/

One awesome feature stands out. Spec blocks can accept an argument, which is a function that can be called to signify the end of an async spec.

describe('User', function(){
describe('#save()', function(){
it('should save without error', function(done){
var user = new User('Luna');
user.save(function(err){
if (err) throw err;
done();
});
})
})
})

To do the same in Jasmine, it might look like this:

describe('User', function(){
describe('#save()', function(){
it('should save without error', function(){
var user, error;

runs(function() {
user = new User('Luna');
user.save(function(err){
error = err;
});
});

waits(100);

runs(function {
expect(error).toBeFalsy();
});

})
})
})

I suppose you could setup a spy, and `waitsFor()` that spy to be called form the callback as well. But the point is this: you have to set all that up. Using the provided callback instead, cleans up the test greatly.

I assume this works by checking the `specFunction.length` and if that is one, then we assume it's an async spec and refuse to move on until that callback is called (or spec times out of course). And if it's zero the spec runs synchronously, or can use waits/runs queues as normal.

I've had to train a few people on Jasmine and the `waits()` and `runs()` dance is always a sticking point of conceptual understanding. But an explicit, "done with everything in this spec" callback is a far easier API to grasp, and requires far less setup in the spec itself. In my opinion it's easier to learn, write, read and maintain.