2015-05-30 4 views
2

Я использую библиотеку базы данных, ее обратный вызов на основе интерфейс выглядит следующим образом:Как я могу исправить этот тест Q.denodify?

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

    } 
} 

Я хочу осуществить обертку вокруг этой базы данных, чтобы преобразовать его в стиле обратного вызова API к API на основе обещания. Для этого я определил следующий класс:

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

Я хочу написать модульный тест, чтобы убедиться, что, когда я называю DatabaseWrapper.insert он вызывает DB.insert. До сих пор мой тест выглядит следующим образом: метод вставки

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

Экземпляр DB является фактически вызывался, как после того, как тест не пройден, как 'insertSpy got called' сообщение выводится в консоли.

Но, по-видимому, он вызывается после того, как тест не удался.

Насколько я знаю, это связано с тем, как работает Node process.nextTick. Таким образом, вызов обратного вызова происходит после завершения теста. Есть ли способ исправить этот тест, не полагаясь на сторонние библиотеки (например, q-flush)?

+0

Это асинхронный тест - используйте асинхронный синтаксис обещания. –

+0

@ Benjamin не могли бы вы предоставить решение в качестве ответа? – h2o

+0

Используете ли вы Mocha для своих тестов? –

ответ

1

Выполнение асинхронного действия, поэтому лучше выполнить асинхронный тест. Добавление 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; 
      }); 
     }) 
    }); 
}); 
Смежные вопросы