我有一个调用使用bluebird promises的方法的模块。这是模块,简化。 Cassandra只是一些能够满足它们的db调用的包装器:
var Cassandra = require('../lib/cassandraObject');
var cassandra = new Cassandra();
exports.doIt = function _doIt(req, res) {
cassandra.queryPromise("query", [1, 2, 3])
.then(function (results) {
res.sendStatus(200);
})
.catch(function(er) {
res.sendStatus(500);
})
}
我试图用sinon和sinon-bluebird测试这个。我为Cassandra的查询承诺存根,并且让res.sendStatus成为间谍:
it("makes a call to doIt", function () {
var qpMock = sinon.stub(Cassandra.prototype, "queryPromise").resolves(['yay!']);
var req = {};
var res = {
sendStatus: sinon.spy(),
};
myModule.doIt(req, res);
expect(qpMock.args[0][1][0]).to.equal(1); //ok
expect(res.sendStatus).to.have.been.calledWith(200); //error ! not called yet!
}
我认为使用这些库时,会立即调用存根的then(),而不是异步调用,但似乎并非如此。 res.sendStatus()调用确实被调用,但是在测试超出范围之后。
有没有办法知道何时调用res.sendStatus()并将其保留在测试范围内,以便我可以断言传递给它的值?
答案 0 :(得分:2)
我建议让doIt()
链接,让它返回承诺:
exports.doIt = function _doIt(req, res) {
return cassandra.queryPromise("query", [1, 2, 3])
.then(function (results) {
res.sendStatus(200);
})
.catch(function(er) {
res.sendStatus(500);
})
}
这样,您可以等待测试用例完成,以便在确定已被调用时检查res.sendStatus()
。
此外,由于Mocha支持开箱即用的承诺,您可以从doIt()
返回承诺,以确保Mocha在继续之前等待您的测试完全完成:
it("makes a call to doIt", function () {
var qpMock = sinon.stub(Cassandra.prototype, "queryPromise").resolves(['yay!']);
var req = {};
var res = { sendStatus: sinon.spy() };
return myModule.doIt(req, res).then(() => {
expect(qpMock.args[0][1][0]).to.equal(1);
expect(res.sendStatus).to.have.been.calledWith(200);
});
})