Testability and Good Design
Michael Feathers addresses the question "How do you test private methods?" in The Deep Synergy Between Testability and Good Design. (If you're stuck in a language with a fetish for compile-time access control on the part of the library writer, you have my sympathy.)
The answer is more interesting than the question. As Michael points out, the desire to test private methods extensively often indicates that he has too much behavior in the class. Other comments suggest that the barrier to creating new classes is too high--we don't do it often enough.
I've often suggested that a major benefit of TDD is that it encourages better design, not only because of YAGNI but because you immediately have to use the API you're designing. If that's painful, or awkward, you may need to refactor. Testability is one part of the aesthetic necessary to write good code.
"I’ve often suggested that a major benefit of TDD is that it encourages better design, not only because of YAGNI but because you immediately have to use the API you’re designing."
|@Daniel, exactly! I've seen a lot of people say that you should document your APIs before you write them, but that seems backwards to me. Executable specifications are so much more useful.|
While the public/protected/private categorization of methods is not as relevant in Perl as it is in Java, many of Feathers' remarks rang true for me. On the one hand, where I have control over the design of the interface and the implementation -- as in my CPAN modules -- I've increasingly found that not only does "[a]iming for testability actually changes your design," it actually improves it. And it certainly improves the implementation: You quickly learn that untestable code is YAGNI code.