Javascript 无法在使用方法调用带有承诺的方法的mocha测试上下文中调用sinon spy

Javascript 无法在使用方法调用带有承诺的方法的mocha测试上下文中调用sinon spy,javascript,node.js,unit-testing,mocha.js,sinon,Javascript,Node.js,Unit Testing,Mocha.js,Sinon,我有一个模块,它调用一个使用bluebird承诺的方法。这是简化的模块。Cassandra只是一些db调用的包装器,它保证了它们: var Cassandra = require('../lib/cassandraObject'); var cassandra = new Cassandra(); exports.doIt = function _doIt(req, res) { cassandra.queryPromise("query", [1, 2, 3]) .then(f

我有一个模块,它调用一个使用bluebird承诺的方法。这是简化的模块。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);
    })
}
我正试图用西农和西农蓝鸟来测试这一点。我中止了对卡桑德拉的查询承诺的调用,并将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()并将其保留在测试范围内,以便我可以对传递给它的值进行断言?

我建议通过让它返回承诺,使
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);
  });
})