Bluebird 承诺在使用 Sinon 的假计时器时冻结
Bluebird promises freeze when using Sinon's fake timer
以下测试在与 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
});
});
});
我正在使用 Mocha (v2.2.5) 与 Bluebird (v2.9.33) 和 Sinon (v1.15.3)。
我尝试了 Bluebird 和 Sinon 的一些讨论中提供的建议,但我无法完成这项工作。这似乎是 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);
});
});
顺便说一句,mocha 内置了对 promise 的支持,所以更好的方法是 return
你的 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!
});
});
根据我的经验,混合使用 promises 和 done
回调风格会导致各种麻烦和难以跟踪的错误。使用 promises 时,尽量坚持返回,并查看 chai-as-promised 等库。我向你保证,它会让你的测试更具可读性!
最佳实践:
不要使用假计时器,它们会导致奇怪的并发问题,因为它们会同步调用延迟函数 - 从而改变执行。而是使用 Mocha 的内置承诺支持:
describe('failing test', function() {
it('test', function(){
return Promise.delay(1000); // return the promise here, no `done`
});
但如果你必须
请不要这样做,但您可以告诉 bluebird 运行 它同步回调,我强烈建议不要这样做,它 会 导致您的应用出现计时问题:
Promise.setScheduler(function(fn){
return fn();
});
以下测试在与 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
});
});
});
我正在使用 Mocha (v2.2.5) 与 Bluebird (v2.9.33) 和 Sinon (v1.15.3)。
我尝试了 Bluebird 和 Sinon 的一些讨论中提供的建议,但我无法完成这项工作。这似乎是 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);
});
});
顺便说一句,mocha 内置了对 promise 的支持,所以更好的方法是 return
你的 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!
});
});
根据我的经验,混合使用 promises 和 done
回调风格会导致各种麻烦和难以跟踪的错误。使用 promises 时,尽量坚持返回,并查看 chai-as-promised 等库。我向你保证,它会让你的测试更具可读性!
最佳实践:
不要使用假计时器,它们会导致奇怪的并发问题,因为它们会同步调用延迟函数 - 从而改变执行。而是使用 Mocha 的内置承诺支持:
describe('failing test', function() {
it('test', function(){
return Promise.delay(1000); // return the promise here, no `done`
});
但如果你必须
请不要这样做,但您可以告诉 bluebird 运行 它同步回调,我强烈建议不要这样做,它 会 导致您的应用出现计时问题:
Promise.setScheduler(function(fn){
return fn();
});