Archive for March, 2011
Encapsulation and testability
Posted by alexander in Designprinciper on March 18, 2011
I’ve come across this pretty much every time when giving talks on TDD and testing, so I thought it’s time to write down my thoughts on the subject. They’re not very original, in fact not original at all, but I’ve tried to find some solid ground at least.
When writing unit tests, you soon end up in a situation where you expose a method more than “proper encapsulation” would require, only to make it testable. In Java this happens through package access, while .NET implementations may be of type internal/[InternalsVisibleTo].
This problem is less common in TDD, but sometimes I feel that I’d prefer another access modifier on my finished code. Personally, I’ve stopped caring about this long ago, but exposing more than the public interface (as in API, not the interface keyword) seems to be a big issue for many people. I’ve found two coping strategies for handling this problem:
- Use interfaces or abstract classes. They become the public part, while the implementation may have slightly more test-friendly access. Again, even this can seem offensive to some people.
- Run all tests through public methods only. This is not the best way to test-drive code, in fact it’s very poor, but it’s doable if your approach is more like developer testing and not strict TDD.
As you see, neither method is perfect, so instead I’m going to present the best argument I’ve found so far for not being overly cautious about “encapsulation” (information hiding) as defined by people who are offended by the difference between internal/package and protected, for example.
I’ve found the second best argument in the book “The art of Unit testing” by Roy Osherove. He does have a “don’t be silly argument”, but the main argument is that test code is a client of the tested API as well, and that this client should be supported. That’s a very good argument, but my favorite is given by Bertrand Meyer in the bible “Object-oriented software construction”. I need to quote here:
“[…] To prove the correctness of a module, you will need to assume some properties about its suppliers. Information hiding means that such proofs are only permitted to rely on public properties of the suppliers, never on their secret properties.”
On the same page Bertrand Meyer argues that information hiding isn’t protection in the sense of security – a physical restriction to the information. A module may very well expose all its members as public and still achieve information hiding if its formal correctness is proven using its public interface. Whether to do this or not is a project management decision, not a technical one.
I’ve found this argument very convincing and sound, and it just happens to support my personal preferences. I hope to convert some non-believers.