Be the first user to complete this post
|
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 runsc1
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:
.eventually
is part of chai-as-promised
Also Read:
- Debugging nodejs applications using node-inspector and Chrome Dev Tools
- Understanding semver versioning for your nodejs packages
- A simple requestAnimationFrame example visually explained
- Organizing your expressjs routes in separate files.
- imperative vs declarative/functional programming