October 20, 2020

Unit Testing Private Methods in Javascript

JavaScript is growing up.  As it matures, we see more and more improvement associated with JavaScript testing and deployments.  One area I get a lot of questions about is unit testing, more specifically, unit testing private methods.

Screen Shot 2016-06-10 at 3.26.18 PM

Traditional revealing module pattern.

When dealing with this issue, there are two main approaches commonly used.   The first is to test the method through another public method that calls it.  The other would be to expose it publicly even if the only thing that needs access to it are the unit tests.  Neither strategy is perfect or ideal but here are a couple of things to consider when choosing which is best for you.

Screen Shot 2016-06-10 at 3.27.03 PM

Testing your private method by calling a public method that calls it.

Start off by considering your objective.  My objective is to be able to make changes to the code-base with confidence.  Additionally, if an issue presents itself, I want to be able to find and address the issue quickly.

When you have several private methods chained together, it becomes no different to test than one big super method.  If there’s a problem with the logic, it can be cumbersome to track down the issue.  On the flip side of that, if every method were public, you could test each method and ensure that it’s doing its little bit of work correctly.  All of the methods doing their one job adds up to a complete workflow.  If one of the methods fails to do its job, it’s quick and easy to identify where the issue lies.   The drawback is that we totally destroyed the notion of a public vs. private methods and all the good things that come along with it.

One approach that I’ve taken with several companies is a hybrid.  I will follow a classic module pattern and expose publicly only those methods that are called externally from outside the class.  Then I create a ‘testObject’ and expose it publicly.  The properties of my testObject are all the private methods that I otherwise would not be able to test.  Now all my private methods are exposed publicly.  While it’s not nearly as safe as keeping them private, at least I know that  I should only ever see ‘class.testOject.somePrivateMethod’ being called from within my unit tests.  If I ever do a code review and see someone calling ‘class.testObject.*’ in the core code, I know someone is calling the private method in a way it’s not intended.

Screen Shot 2016-06-10 at 3.28.18 PM

Hybrid testing pattern. Exposing your private methods through a single test object.

It’s a great pattern and has worked very well for several enterprise implementations.  It’s not perfect but is a good compromise in most cases.  You’ll want to consider your application and the pros and cons of the various strategies before deciding which is best for you.

Nick Stark is a Principal Consultant at DomGeek. He is a leading expert in web and mobile technologies.

3 Comments

  1. Piotr Nalepa Reply

    I don’t agree with the pattern you proposed. If there any private methods in your code and you want to test them, then you should test them in the context of functionality, not in the context of method itself. The private methods are meant to help you with delivering a functionality to end user. If your code is nothing like a framework, then testing private methods is just a bad approach and should be avoided.

  2. Niels Reply

    Testing private methods is really bad. In this approach you’re exposing privates methods to production code, which is even worse. Private methods are there to be private, they allow you to split up your code in smaller chunks, nothing more nothing less. If you test private methods:

    – Code coverage is USELESS, because sure, it will get 100%, but you still no idea if all functionalities are actually tested. Private methods should be touched in you’re unit tests and code coverage will reveal that.
    – Code can NOT be changed with more confidence, you do not test if you actually keep functionality working when you change code, you just test if the individual methods work.

    No approach to testing private methods is ‘best for you’. Don’t test private methods.. For more information there is a lot of TDD/Unit test books and material out there.

    1. divp Reply

      Unit testing is a software development process
      in which the smallest testable parts of an application, called units,
      are individually and independently scrutinized for proper operation…nicely explained

Leave a Reply

Your email address will not be published. Required fields are marked *