The following test freezes when used with Sinon's fake timers and Bluebird.
var sinon = require('sinon');
var Promise = require('bluebird');
describe('failing test', function() {
beforeEach(function() {
this.clock = sinon.useFakeTimers();
});
afterEach(function() {
this.clock.restore();
});
it('test', function(done) {
Promise.delay(1000).then(function(){
done(); //This never gets called
});
});
});
I am using Mocha (v2.2.5) with Bluebird (v2.9.33) and Sinon (v1.15.3).
I tried the suggestions offered in some discussions in Bluebird and Sinon but I couldn't make this work. This seems to be an issue with the way Sinon stubs setImmediate but other than that I have no clue how to resolve this.
You need to step the fake timer manually like so:
describe('failing test', function() {
it('test', function(done) {
Promise.delay(1000).then(function(){
done(); //This never gets called
});
//
// ADVANCE THE CLOCK:
//
this.clock.tick(1000);
});
});
Btw, mocha has built-in support for promises, so an even better way to do this would be to return
your promise:
describe('failing test', function() {
it('test', function() { // No more "done" callback
var p = Promise.delay(1000).then(function(){
console.log('done');
});
this.clock.tick(1000);
return p; // Return the promise instead - mocha will take of the async magic goodness!
});
});
From my experience, mixing promises and the done
callback style leads to all sorts of trouble and hard to track errors. When using promises, try to stick with returning, and have a look at a library such as chai-as-promised. I promise you it'll make your tests much more readable!
Don't use fake timers, they can cause weird concurrency issues because they synchronously call deferred functions - thus changing execution. Instead use Mocha's built in promises support as:
describe('failing test', function() {
it('test', function(){
return Promise.delay(1000); // return the promise here, no `done`
});
Please don't, but you can tell bluebird to run its then callbacks synchronously, I strongly recommend against this and it will cause timing issues in your app:
Promise.setScheduler(function(fn){
return fn();
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With