nicangeli nicangeli - 1 year ago 192
Node.js Question

Unit testing multiple asynchronous calls that return promises with Mocha

I'm trying to understand how to best unit test my asynchronous CommonJS modules. I'm struggling to understand best practice when dealing with multiple chained promises.

Lets assume I have the following module defined:

module.exports = function(api, logger) {
return api.get('/foo')
.then(res => {
return'/bar/' +
.then(res => {
.catch(err => {

and I have the following spec file trying to test that the correct calls are made.

var module = require('./module')
describe('module()', function() {
var api;
var logger;
var getStub;
var postStub;
beforeEach(function() {
getStub = sinon.stub();
postStub = sinon.stub();
api = {
get: getStub.resolves({id: '123'),
post: postStub.resolves()
logger = {
log: sinon.spy(),
error: sinon.spy()
afterEach(function() {
it('should call get and post', function(done) {
module(api, logger) // System under test

This doesn't work. The first assertion passes correctly, but the second assertion fails, as presumably the promise hasn't resolved at the time of execution.

I can fix this using process.nextTick or setTimeout but I'd like to see how other people have solved this more gracefully.

I've tried adding chai-as-promised into the mix with little luck. My current setup includes, sinon, chai, sinon-as-promised and sinon-chai.


Answer Source

You should use the fact that module() returns a promise, so you can add another .then() to the chain where you can assert the arguments (because at that point the previous .then() steps have been called, including the call to

And since Mocha supports promises, you can return the resulting promise instead of having to deal with done:

it('should call get and post', function() {
  return module(api, logger).then(() => {
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download