nass
nass

Reputation: 347

Mocha: testing function used in constructor

I am using mocha, chai and sinon for my testing purposes. I've got a class like below:

class ClassToTest {
    person;

    constructor(person) {
        this.setPerson(person);
    }

    setPerson(person) {
        if (typeof person.firstName === 'undefined') {
            throw Error('Person has to have first name.');
        }

        this.person = person;
    }
}

How I can test setPerson function? When I create new ClassToTest object setPerson gets called by constructor and Error gets thrown immediately. I've tried creating stubs with Sinon but no luck so far.

Should I even test setPerson function to begin with? I was thinking about: 1. moving validation (typeof if) to other function (e.g. validatePerson) and test that 2. testing only if constructor throws Error or sets person

Upvotes: 1

Views: 2181

Answers (1)

Lin Du
Lin Du

Reputation: 102207

Here is the unit test solution:

index.ts:

export class ClassToTest {
  person;

  constructor(person) {
    this.setPerson(person);
  }

  setPerson(person) {
    if (typeof person.firstName === 'undefined') {
      throw new Error('Person has to have first name.');
    }

    this.person = person;
  }
}

index.test.ts:

import { ClassToTest } from './';
import sinon from 'sinon';
import { expect } from 'chai';

describe('57091171', () => {
  afterEach(() => {
    sinon.restore();
  });
  describe('#constructor', () => {
    it('should set person', () => {
      const setPersonStub = sinon.stub(ClassToTest.prototype, 'setPerson');
      const person = { firstName: 'sinon' };
      new ClassToTest(person);
      sinon.assert.calledWithExactly(setPersonStub, person);
    });
  });
  describe('#setPerson', () => {
    it('should set person', () => {
      const stub = sinon.stub(ClassToTest.prototype, 'setPerson').returns();
      const person = { firstName: 'sinon' };
      const ins = new ClassToTest(person);
      stub.restore();
      ins.setPerson(person);
      expect(ins.person).to.deep.equal(person);
    });
    it('should handle error if firstName is not existed', () => {
      const stub = sinon.stub(ClassToTest.prototype, 'setPerson').returns();
      const person = {};
      const ins = new ClassToTest(person);
      stub.restore();
      expect(() => ins.setPerson(person)).to.throw('Person has to have first name.');
    });
  });
});

unit test results with 100% coverage:

  57091171
    #constructor
      ✓ should set person
    #setPerson
      ✓ should set person
      ✓ should handle error if firstName is not existed


  3 passing (43ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 index.ts |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------

Upvotes: 2

Related Questions