Join any discussion about unit testing and there's one question that will invariably come up: how do you test private methods?

There are a number of answers. Some people advocate increased visibility. They say that if you feel that you must test a private method, it's really no great sin to make it protected, public or package private in order to make it testable.

Other people say that you can use special tools to access private methods. In Java, at least, you can quite easily rig something up with reflection to give you any kind of access you'd like.

These are "okay" answers, but really they are missing something. When I write tests and I have the urge to test a private method, I take it as a hint. The hint tells me that my class is encapsulating so much that it has ceased to be "understandable" by tests through its public interface. I listen to the hint, and factor my design differently. Usually, I end up moving the private method (and possibly some methods around it) to a new class where it can be non-private and accessible to tests.

Aiming for testability actually changes your design.

But, is that good?

The answer for me, so far, has been yes. There appears to be a synergy between testability (at the unit level) and good design. If you aim for testability and make some good choices, design gets better. If you aim for good design, your design becomes more testable.

In the end, it all comes down to cohesion and coupling. If classes are deeply coupled with their neighbors, it is hard to control them in a test or observe them independently. If a class isn't cohesive, it may have some logic which is not easily exercisable through its public interface.

It seems that reverse is true also. Classes which are hard to instantiate and use in a test harness are more coupled than they could be, and classes with private methods that you feel the urge to test, invariably have some sort of cohesion problem: they have more than one responsibility.

I suspect that some people reading this might think it is a load of wishful thinking, or that this synergy between testability and good design is just a hypothesis without much to back it. All I can say is that in the community of people doing test-driven development there are a number of people who have found that this question of testing private methods doesn't come up much in their practice. They target both testability and good design and find that both goals nurture each other.

Is the synergy real? I think it is. When a bit of functionality is not easily understood by a test at the public interface, the chances of it being easily understood by a human are ridiculously low. And, if there is any universal baseline for good design it has to be understandability.

So, having said all of this, I end this blog with a challenge: Can anyone come up with an example in which there is a private method that they feel that they have to test.. something that they don't feel comfortable testing through the public interface of the class, but which can't be made testable with a better design?