我怎样才能解决这个Q.denodifytesting?

我正在使用一个数据库库,其基于callback的界面如下所示:

var DB = { insert: function(options, callback) { } } 

我想实现一个包装这个数据库来将其callback风格API转换为基于承诺的API。 要做到这一点,我已经定义了以下类:

 var DatabaseWrapper = { init: function(db) { this.db = db; }, insert: function(options) { return Q.denodeify(this.db.insert.bind(this.db))(options); } } 

我想写一个unit testing,以确保当我调用DatabaseWrapper.insert它调用DB.insert 。 到目前为止,我的testing如下所示:

 describe('DatabaseWrapper', function () { var wrapper, insertSpy, bindStub; beforeEach(function () { wrapper = Object.create(DatabaseWrapper); insertSpy = sinon.spy(function () { console.log('insertSpy got called'); }); bindStub = sinon.stub(); wrapper.db = { insert: function (options, callback) { } }; sinon.stub(wrapper.db.insert, 'bind').returns(insertSpy); }); describe('#insert', function () { it('should delegate to db.insert', function (done) { wrapper.insert({herp: 'derp'}); expect(wrapper.db.insert.bind).to.have.been.calledOnce; // This fails but I expect it to succeed expect(promise).to.have.been.calledOnce; }) }); }); 

数据库实例的插入方法实际上是在testing失败后调用的,因为在控制台中打印了'insertSpy got called'消息。

但显然它在testing失败后被调用。

据我所知,这是由于Node的process.nextTick工作方式。 所以在testing失败之后发生callback。 有没有办法可以解决这个testing,而不依赖于第三方库(例如q-flush )?

您正在执行asynchronous操作,因此最好执行asynchronoustesting。 添加一个setTimeout仍然容易出现竞争条件。

 describe('#insert', function () { it('should delegate to db.insert', function () { // no done here // note the return here to signal to mocha this is a promise test return wrapper.insert({herp: 'derp'}).then(function(){ // add expects here, rest of asserts should happen here expect(wrapper.db.insert.bind).to.have.been.calledOnce; }); }) }); });