Unit-testing – How to avoid the need to Unit test private methods

mockingunit testing

I know you're not supposed to test private methods, and if it looks like you need to, there might be a class in there waiting to come out.

But, I don't want to have a gazillion classes just so that I can test their public interfaces and I find that for many classes if I just test the public methods I end up having to mock a lot of dependencies and the unit tests are enormous and hard to follow.

I much prefer mocking the private methods when testing the public ones, and mocking external dependencies when testing the private ones.

Am I crazy?

Best Answer

You're partially right - you shouldn't directly test private methods. The private methods on a class should be invoked by one or more of the public methods (perhaps indirectly - a private method called by a public method may invoke other private methods). Therefore, when testing your public methods, you will test your private methods as well. If you have private methods that remain untested, either your test cases are insufficient or the private methods are unused and can be removed.

If you are taking a white-box testing approach, you should consider the implementation details of your private methods when constructing unit tests around your public methods. If you are taking a black-box approach, you shouldn't be testing against any implementation details in either the public or private methods but against the expected behavior.

Personally, I prefer a white-box approach to unit tests. I can craft tests to put the methods and classes under test into different states that cause interesting behavior in my public and private methods and then assert that the results are what I expect.

So - don't mock your private methods. Use them to understand what you need to test in order to provide good coverage of the functionality that you provide. This is especially true at the unit test level.