在使用承诺调用方法的方法的摩卡testing环境中无法调用sinon间谍

我有一个模块,调用一个使用蓝鸟承诺的方法。 这里是简化的模块。 卡桑德拉只是一些数据库调用的包装,

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

我试图用sin和蓝鸟来testing。 我将存储卡桑德拉的查询承诺的存根,我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! } 

我以为这些库会立即调用stub的then()而不是asynchronous的,但是这似乎并不是这样。 res.sendStatus()调用确实被调用,但在testing超出范围之后。

有没有什么办法知道什么时候res.sendStatus()被调用,并保持在testing范围内,所以我可以断言传递给它的值?

我会build议使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); }) } 

这样,您可以等待testing用例完成,以便在确定已调用res.sendStatus()时检查它。

此外,由于摩卡支持开箱即用的承诺,您可以从doIt()返回承诺,以确保摩卡等待您的testing完全完成,然后再继续:

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