Here we have a simple class to be tested that returns a Promise based on the results of an external ResponseProcessor that takes time to execute.

For simplicty we’ll assume that the processResponse method won’t ever fail.

import {processResponse} from '../utils/response_processor';

const ping = () => {
  return new Promise((resolve, _reject) => {
    const response = processResponse(data);
    resolve(response);
  });
}

module.exports = ping;

To test this we can leverage the following tools.

  1. [mocha](<https://mochajs.org/>)
  2. [chai](<http://chaijs.com/>)
  3. [sinon](<http://sinonjs.org/>)
  4. [proxyquire](<https://github.com/thlorenz/proxyquire>)
  5. [chai-as-promised](<https://github.com/domenic/chai-as-promised>)

I use the following test script in my package.json file.

"test": "NODE_ENV=test mocha --compilers js:babel-core/register --require ./test/unit/test_helper.js  --recursive test/**/*_spec.js"

This allows me to use es6 syntax. It references a test_helper that will look like

import chai from 'chai';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import chaiAsPromised from 'chai-as-promised';
import sinonStubPromise from 'sinon-stub-promise';

chai.use(sinonChai);
chai.use(chaiAsPromised);
sinonStubPromise(sinon);

Proxyquire allows us to inject our own stub in the place of the external ResponseProcessor. We can then use sinon to spy on that stub’s methods. We use the extensions to chai that chai-as-promised injects to check that the ping() method’s promise is fullfilled, and that it eventually returns the required response.

import {expect}       from 'chai';
import sinon          from 'sinon';
import proxyquire     from 'proxyquire';

let formattingStub = {
  wrapResponse: () => {}
}

let ping = proxyquire('../../../src/api/ping', {
  '../utils/formatting': formattingStub
});

describe('ping', () => {
  let wrapResponseSpy, pingResult;
  const response = 'some response';

  beforeEach(() => {
    wrapResponseSpy = sinon.stub(formattingStub, 'wrapResponse').returns(response);
    pingResult = ping();
  })

  afterEach(() => {
    formattingStub.wrapResponse.restore();
  })

  it('returns a fullfilled promise', () => {
    expect(pingResult).to.be.fulfilled;
  })

  it('eventually returns the correct response', () => {
    expect(pingResult).to.eventually.equal(response);
  })
});

Now instead let’s assume you wish to test something that uses the response from ping.

import {ping} from './ping';

const pingWrapper = () => {
  ping.then((response) => {
    // do something with the response
  });
}

module.exports = pingWrapper;

To test the pingWrapper we leverage

  1. [sinon](<http://sinonjs.org/>)
  2. [proxyquire](<https://github.com/thlorenz/proxyquire>)