On private methods
While reviewing some code recently, I noticed a significant number of private methods being used within classes. This made me consider the usefulness of private methods and prompted me to reflect on the implications of such practices. In this article, I summarized my considerations with respect to the usage of private methods and especially the consequences for unit testing.
Reasoning behind private methods
When designing a class, one should keep other developers in mind, which might use the class, especially when building a reusable module or library. In this context, private methods may seem to make sense, as they can hide implementation details that should not be exposed to developers using the class, thereby providing a clear and understandable interface.
Furthermore, private methods can be used to decompose the complexity within a public method into more fine-grained parts. This could, in principle, make the code more comprehensible for developers maintaining it.
However, the use of private methods can complicate the use of unit testing. It prevents the test code from calling these methods directly. Private methods can only be accessed indirectly via the public methods. If private methods again call private methods it could get even more complicated.
Within a classical test driven development cycle one might end up with private methods after several red-green-refactor steps. I am not convinced that the final result of a red-green-refactor cycle
Alternatives to private methods
Workarounds to test private methods
In the following I want to list a few approaches to deal with private methods. Either to avoid them with an alternative approach or to workaround them, but allow to test them directly.
Separate interface and implementation
Reflection
Testing inherited class with private methods exposed
Prefix with underscore
Create a separate class
Conclusion
Private class properties make total sense, as they prevent changing the internal state of a class from the outside. Also a private constructor could be useful to enforce a singleton pattern. However, at least in my opinion, private methods make things just complicated and don't add any value. Thus, I would rather avoid them completely.