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

Geo*_*ous 10 node.js sinon bluebird

当与Sinon的假定时器和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     
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

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

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

Bad*_*ion 8

您需要手动步进假计时器,如下所示:

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);
  });
});
Run Code Online (Sandbox Code Playgroud)

顺便说一下,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!
  });
});
Run Code Online (Sandbox Code Playgroud)

根据我的经验,混合承诺和done回调风格会导致各种麻烦并且很难跟踪错误.使用promises时,尽量坚持返回,并查看像chai-as-promised这样的库.我保证你会让你的测试更具可读性!