Search code examples
node.jssinonchaisinon-chai

Stubbing out a promise inside a method using chai and sinon


My function under test looks roughly like this;

  function doThing(data, callback) {

    externalService.post('send').request(data)
        .then(() => {
          if (callback) { callback(); }
        })
        .catch((message) => {
          logger.warn('warning message');
          if (callback) { callback(); }
        });
  }

And I am trying to test this using Chai and Sinon.

I've tried following different guides, my current incantation looks like;

const thingBeingTested = require('thing-being-tested');
const chai = require('chai');
const sinon = require('sinon');
require('sinon-as-promised');
const sinonChai = require('sinon-chai');
const expect = chai.expect;

var chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
chai.use(sinonChai);

describe('The Thing', () => {  
  it('should run a callback when requested and successful', done => {

    const externalService = { post: { request: sinon.stub() } };
    const callback = sinon.spy();

    externalService.post.request.resolves(callback);

    doThing({...}, callback);
    expect(callback).to.have.been.called;
    done();
  });
});

I cannot get externalService.post stubbed out correctly. Any help would be greatly appreciated.

I am completely new to Chai and Sinon – so fully expect to be doing something stupid.


Solution

  • Your doThing function has no access to const externalService from your test. I will assume that your main file has smth like

    const externalService = require('./external_service');
    

    to get it.

    In your test you should get the same externalService too:

    describe(..., () => {
        it(..., () => {
            // adjust the path accordingly
            const externalService = require('./external_service');
    

    and then mock its method:

    sinon.stub(externalService, 'post').returns({
        request: sinon.stub().resolves(callback)
    });
    

    Then you can call doThing and analyze the results.

    After the test is complete, don't forget to restore the original post by

    externalService.post.restore();