我有一个模块调用一个使用 bluebird promises 的方法。这是模块,已简化。 Cassandra 只是一些数据库调用的包装器, promise 它们:
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 对此进行测试。我 stub 调用 Cassandra 的查询 promise ,并使 res.sendStatus 成为 spy :
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!
}
我认为对于这些库,stub 的 then() 将被立即调用而不是异步调用,但事实似乎并非如此。 res.sendStatus() 调用确实被调用,但在测试超出范围之后。
有什么方法可以知道何时调用 res.sendStatus() 并将其保留在测试范围内,以便我可以断言传递给它的值?
最佳答案
我建议让 doIt()
可链接,让它返回 promise :
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 支持开箱即用的 promise,您可以从 doIt()
返回 promise 以确保 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);
});
})
关于javascript - 无法在 mocha 测试的上下文中调用 sinon spy ,方法是使用 promises 调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37372058/