Be the first user to complete this post

  • 0
Add to List

Testing promise sequence using mocha, chai, chai-as-promised, sinon


System Under Test

Let's say we have a method call sequence to run promise based commands in sequence. For example, below command runs c1 and when it resolves it will run c2 and so forth.
Util.sequqnce([c1, c2, c3]);  // c1, c2, c3 are promises.
.sequence takes an array of promises and returns a value returned by the last resolved promise as shown below.

class Util {

    sequence(list) {
        return list.reduce(
            (prev, item) => prev.then(() => this.run(item)),
            Promise.resolve()
        );
    }

}

module.exports = Util;

NOTE: .sequence calls .run command to execute the item.

Configuration

We will require mocha ( test runner ), chai ( assertion library ), sinon( spy, stub, mock ), chai-as-promised ( to test promises ) as devDependencies in out package.json.

{
  ...

  "devDependencies": {
    "chai": "4.1.1",
    "chai-as-promised": "7.1.1",
    "istanbul": "0.4.5",
    "mocha": "3.5.0",
    "sinon": "3.2.1",
  },

  ...

}


Test case

If the commands, c1, c2, c3 when fulfilled returns 10, 20, 30 respectively - First time, .run is called with c1 which returns 10 - Second time, .run is called with c2 which returns 20 - Third time, .run is called with c3 which returns 30
const Util = require('../scripts/Util.js');

const chai = require('chai');
const sinon = require('sinon');
const chaiAsPromised = require('chai-as-promised');

// set up the middleware
chai.use(chaiAsPromised);

describe('Util', () => {

  describe('sequence', () => {

    it('Expect all the comands to run in sequence', () => {

      let util = new Util();

      // create an array of promises which resolves immediately
      let promises = [10, 20, 30].map( item => Promise.resolve(item) );

      // spy an existing function so we can inspect it
      spy = sinon.spy(util, 'run');

      // return notifies mocha to wait for the promise to be resolved
      return util.sequence(promises)
        .then(() => expect(spy.firstCall.returnValue).to.eventually.equal(10))
        .then(() => expect(spy.secondCall.returnValue).to.eventually.equal(20))
        .then(() => expect(spy.thirdCall.returnValue).to.eventually.equal(30));

      });

  });


    it('verify sequence execution by updating the result array', () => {

        let result = [],
            util = new Util();

        p3 = () => new Promise((resolve, reject) => {
            result.push(100);

            setTimeout(() => {
                result.push(200);
                resolve();
            }, 10);
        });

        p4 = () => new Promise((resolve, reject) => {
            result.push(300);
            resolve();
        });

        return util.run([ p3, p4 ]).then(() => {
            expect(result).to.have.ordered.members([ 100, 200, 300 ]);
        });

    });

});

Notes:




Also Read:

  1. Resolved - sudo npm command not found
  2. gzip compress and cache api response in express
  3. What is an npmignore file and what is it used for
  4. Unit test your Nodejs RESTful API using mocha
  5. exports is not defined