Reputation: 937
When I'm testing with Mocha, I often have a combination of both asynchronous and synchronous tests that need to run.
Mocha handles this beautifully allowing me to specify a callback, done
, whenever my tests are asynchronous.
My question is, how does Mocha internally observe my tests and know that it should wait for asynchronous activity? It seems to wait anytime I have the callback parameter defined in my test functions. You can see in the examples below, the first test should timeout, the second should proceed and finish before user.save
calls the anonymous function.
// In an async test that doesn't call done, mocha will timeout.
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;
});
})
})
})
// The same test without done will proceed without timing out.
describe('User', function(){
describe('#save()', function(){
it('should save without error', function(){
var user = new User('Luna');
user.save(function(err){
if (err) throw err;
});
})
})
})
Is this node.js specific magic? Is this something that can be done in any Javascript?
Upvotes: 15
Views: 4168
Reputation: 706
This is simple pure Javascript magic.
Functions are in fact objects, and they have properties (such as the number of parameters are defined with the function).
Look at how this.async is set in mocha/lib/runnable.js
function Runnable(title, fn) {
this.title = title;
this.fn = fn;
this.async = fn && fn.length;
this.sync = ! this.async;
this._timeout = 2000;
this._slow = 75;
this.timedOut = false;
}
Mocha's logic changes based whether or not your function is defined with parameters.
Upvotes: 22
Reputation: 437
What you're looking for is Function's length property which can tell how many arguments a function is expecting. When you define a callback with done
it can tell and treats it asynchonously.
function it(str, cb){
if(cb.length > 0)
//async
else
//sync
}
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/Length
Upvotes: 4