Reputation: 1768
I have a module that calls a method that uses bluebird promises. Here is the module, simplified. Cassandra is simply a wrapper around some db calls that promisfies them:
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);
})
}
I'm attempting to test this with sinon and sinon-bluebird. I stub the call for Cassandra's query promise, and I make res.sendStatus a 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!
}
I thought with these libraries, the then() of the stubs would be called immediately and not asynchronously, but this does not seem to be the case. The res.sendStatus() call does get called, but after the test is out of scope.
Is there any way to know when the res.sendStatus() gets called and keep it in the scope of the test so I can assert on the value passed to it?
Upvotes: 1
Views: 571
Reputation: 203534
I would suggest making doIt()
chainable, by having it return the 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);
})
}
That way, you can wait for completion in your test case so you check res.sendStatus()
when you're sure it has been called.
Also, since Mocha supports promises out of the box, you can return the promise from doIt()
to make sure Mocha waits for your test to be fully complete before continuing:
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);
});
})
Upvotes: 2