user2818541
user2818541

Reputation: 111

How to mock constructor call in javascript

How do i mock creating constructor of my parent class in derived class.

here is the example i am testing.

myclass.js

class a {

  constructor() {
     console.log('i am from class a constructor');
   }
  foo() {
    console.log('i am from class a foo method');
  }
}


class b {

  constructor() {
     console.log('i am from class b constructor');
   }
  baz() {
    let obj = new a();
    a.foo();
    console.log('i am from class b baz method');
  }
}

Here is my unittest, using Sinon.js i am mocking. i am creating unittest for class b -> baz() method. my expectation is to calling baz() method should not call actual class a and it should not print console which is in class a constructor.how can i achive this. sinon.createStubInstance() i used to create object but how to mock constructor?

myclass.test.js

describe('myclass' ()=> {
   it('should not call class a constructor', (done) => {
    let b_obj = new b()
    b_obj.baz();
    done()
   });
})

Output printing for above code

i am from class a constructor
i am from class a foo method
i am from class b baz method

Expected Output for above code

// should be mocked .. i am from class a constructor
//should be mocked .. i am from class a foo method
i am from class b baz method

Upvotes: 0

Views: 1574

Answers (1)

Lin Du
Lin Du

Reputation: 102207

I made a few refactors and using proxyquire to mock class a.

E.g.

a.js:

class a {
  constructor() {
    console.log('i am from class a constructor');
  }
  foo() {
    console.log('i am from class a foo method');
  }
}

module.exports = a;

b.js:

const a = require('./a');

class b {
  constructor() {
    console.log('i am from class b constructor');
  }
  baz() {
    let obj = new a();
    obj.foo();
    console.log('i am from class b baz method');
  }
}

module.exports = b;

b.test.js:

const b = require('./b');
const sinon = require('sinon');
const proxyquire = require('proxyquire');

describe('61108610', () => {
  it('should pass', () => {
    const aInstanceStub = { foo: sinon.stub() };
    const aStub = sinon.stub().returns(aInstanceStub);
    const b = proxyquire('./b', {
      './a': aStub,
    });
    const logSpy = sinon.spy(console, 'log');
    const b_obj = new b();
    b_obj.baz();
    sinon.assert.calledOnce(aStub);
    sinon.assert.calledOnce(aInstanceStub.foo);
    sinon.assert.calledWithExactly(logSpy, 'i am from class b baz method');
  });
});

unit test results with coverage report:

  61108610
i am from class b constructor
i am from class b baz method
    ✓ should pass


  1 passing (30ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |   77.78 |      100 |      50 |   77.78 |                   
 a.js     |   33.33 |      100 |       0 |   33.33 | 3,6               
 b.js     |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------

source code: https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/61108610

Upvotes: 1

Related Questions