unit-testingtypescriptmocha.js

How to unit test private methods in Typescript


When I tried to do unit testing for private methods in a Class getting error as private methods are only accessible inside the class. Here I added sample snippet for my class and mocha test. Kindly provide me solution to implement unit test for private methods.

Class Name: Notification.ts

class Notification {
 constructor() {}
 public validateTempalte() {
  return true;
 }

 private replacePlaceholder() {
  return true;
 }
}

Unit Test:

import {Notification} from 'Notification';
import * as chai from "chai";

describe("Notification", function(){

  describe('#validateTempalte - Validate template', function() {
      it('it should return success', function() {
        const result = new Notification()
        chai.expect(result.validateTempalte()).to.be.equal(true);
      });
    });
  describe('#replacePlaceholder - Replace Placeholder', function() {
      it('it should return success', function() {
        const result = new Notification()
        // As expected getting error "Private is only accessible within class"
        chai.expect(result.replacePlaceholder()).to.be.equal(true);
      });
    });
});

As a workaround, currently, I am changing access specifier of function replacePlaceholder to public. But I don't think its a valid approach.


Solution

  • Technically, in current versions of TypeScript private methods are only compile-time checked to be private - so you can call them.

    class Example {
        public publicMethod() {
            return 'public';
        }
    
        private privateMethod() {
            return 'private';
        }
    }
    
    const example = new Example();
    
    console.log(example.publicMethod()); // 'public'
    console.log(example.privateMethod()); // 'private'
    

    I mention this only because you asked how to do it, and that is how you could do it.

    Correct Answer

    However, that private method must be called by some other method... otherwise it isn't called at all. If you test the behaviour of that other method, you will cover the private method in the context it is used.

    If you specifically test private methods, your tests will become tightly coupled to the implementation details (i.e. a good test wouldn't need to be changed if you refactored the implementation).

    Disclaimer

    If you still test it at the private method level, the compiler might in the future change and make the test fail (i.e. if the compiler made the method "properly" private, or if a future version of ECMAScript added visibility keywords, etc).