Freigeben über


How to test private methods

A question that arises from time to time is how to test private methods. Assuming we're using BDD/TDD the first counter-question is: If you're using BDD how did you create the private method in the first place? I guess there are two relevant answers to this question. Either you have some private method that is made private in order to make the compiler not create implicit methods. This is quite common in C++ in order to prevent implicit type conversions and to hide some operator. The body of the method in these cases is always empty or throws an exception. The other relevant answer is that you have tests covering the private method indirectly but a bug (or new requirement) makes you want to test the method directly because it is impossible indirectly.

To handle the "private methods to trick the compiler" situation I think you have to be pragmatic. You're doing things in order to make sure you get compiler errors for things you don't want to do. Frankly I don't think it makes much sense in having tests for these things. Just accept that this is OK.

In the case where you have a private method that you want to start testing directly you basically have two options. The fastest and also the ugliest thing to do is to make the private method protected and then subclass that object to get access to the protected method. This will however not work at all if the class is sealed. Also you're now exposing what was intended to be internal implementation specific things to everybody that inherits from your object. So you're actually changing the behavior of the object quite radically and that is not a good thing. A much better approach is to break out the functionality in the private method into a new class. In this class the previously private method will be public so it is easy to reuse the object elsewhere. Also much easier to test since you need no sub classing.

Finally I want to mention that having specific tests for private methods are a bad code smell. Either the functionality is so complex that it should have been a separate object in the first place or you should be able to test the functionality of the private method indirectly as parts of other tests. There is no point in having one test for each method in each class - you should have one test for each behavior (at both high and low level) in your application.