Bluebird承诺在使用Sinon的假计时器时会冻结

时间:2015-07-14 10:15:48

标签: node.js sinon bluebird

以下测试在与Sinon的假定时器和Bluebird一起使用时冻结。

for (int i = 0; i < columns; i++)
{
   sum += left.elements[x + i * columns] * right.elements[i + y * columns];
}

我正在使用Mocha(v2.2.5)和Bluebird(v2.9.33)以及Sinon(v1.15.3)。

我尝试了在Bluebird和Sinon的一些讨论中提出的建议,但我无法做到这一点。这似乎是Sinon存根setImmediate的方式的问题,但除此之外我不知道如何解决这个问题。

2 个答案:

答案 0 :(得分:7)

您需要手动步进假计时器:

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);
  });
});

顺便说一句,mocha已经内置了对promises的支持,所以更好的方法就是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回调样式会导致各种麻烦并难以跟踪错误。使用promises时,尽量坚持返回,并查看chai-as-promised等库。我保证你会让你的测试更具可读性!

答案 1 :(得分:2)

最佳做法:

不要使用假定时器,它们会导致奇怪的并发问题,因为它们会同步调用延迟函数 - 从而改变执行。而是使用Mocha内置的承诺支持:

describe('failing test', function() {
    it('test', function(){ 
        return Promise.delay(1000); // return the promise here, no `done`
    });

但是如果你必须

请不要,但是你可以告诉蓝鸟同步运行它的回调,我强烈建议不要这样做,导致你的应用中的时间问题:

Promise.setScheduler(function(fn){
    return fn();
});