Search code examples
javascriptnode.jsunit-testingmockingsinon

Mocking JavaScript constructor with Sinon.JS


I'd like to unit test the following ES6 class:

// service.js
const InternalService = require('internal-service');

class Service {
  constructor(args) {
    this.internalService = new InternalService(args);
  }

  getData(args) {   
    let events = this.internalService.getEvents(args);
    let data = getDataFromEvents(events);
    return data;
  }
}

function getDataFromEvents(events) {...}

module.exports = Service;

How do I mock constructor with Sinon.JS in order to mock getEvents of internalService to test getData?

I looked at Javascript: Mocking Constructor using Sinon but wasn't able to extract a solution.

// test.js
const chai = require('chai');
const sinon = require('sinon');
const should = chai.should();

let Service = require('service');

describe('Service', function() {
  it('getData', function() {
    // throws: TypeError: Attempted to wrap undefined property Service as function
    sinon.stub(Service, 'Service').returns(0);
  });
});

Solution

  • You can either create a namespace or create a stub instance using sinon.createStubInstance (this will not invoke the constructor).

    Creating a namespace:

    const namespace = {
      Service: require('./service')
    };
    
    describe('Service', function() {
      it('getData', function() {
        sinon.stub(namespace, 'Service').returns(0);
        console.log(new namespace.Service()); // Service {}
      });
    });
    

    Creating a stub instance:

    let Service = require('./service');
    
    describe('Service', function() {
      it('getData', function() {
        let stub = sinon.createStubInstance(Service);
        console.log(stub); // Service {}
      });
    });