当使用Sinon的假定时器时,蓝鸟承诺冻结
与Sinon的假定时器和Bluebird一起使用时,以下testing会冻结。
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 }); }); });
我正在用Bluebird(v2.9.33)和Sinon(v1.15.3)使用Mocha(v2.2.5)。
我尝试了Bluebird和Sinon在一些讨论中提出的build议,但是我无法做到这一点。 这似乎是一个问题与方式Sinon存根setImmediate但除此之外,我不知道如何解决这个问题。
您需要像这样手动步骤假计时器:
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); }); });
顺便说一下,摩卡已经内置了对promise的支持,所以更好的方法是return
你的诺言:
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! }); });
根据我的经验,混合的承诺和done
callback风格导致各种麻烦和难以追踪错误。 在使用承诺时,尽量坚持回头看看图书馆,比如答应答 。 我向你保证它会使你的testing更加可读!
最佳做法:
不要使用假定时器,它们会导致奇怪的并发问题,因为它们同时调用延迟函数 – 从而改变执行。 而是使用摩卡的内置承诺支持:
describe('failing test', function() { it('test', function(){ return Promise.delay(1000); // return the promise here, no `done` });
但是,如果你必须的
请不要,但你可以告诉蓝鸟同步运行它的callback,我强烈build议不要这样做,它会导致你的应用程序的计时问题:
Promise.setScheduler(function(fn){ return fn(); });