I can’t be the only one glad that the Google Testing Blog has become active again (and I don’t mean “we’re having a conference on another continent” style posts, much as I eagerly await those missives. But this post has actually crystallized my understanding of one aspect of designing for testability. There are probably some who will regard this one as old news. It is, however, pretty fundamental. To summarize, it says that any given class should either create objects or use them.
So, let’s assume most of your objects are constructed using auto-wiring of dependencies. We can ignore cases like
List<T>, since they’ve got no externalities and have well-known behaviour. That still leaves us with some cases where we need to use an object that’s only purpose is to create other, specific, objects. Which is, of course, the abstract factory pattern. Now, anyone who’s skimmed the Gang of Four book (and let’s face it, most of us skimmed it) will know the pattern, although they’ll probably have trouble remembering which way around Abstract Factory and Factory go. (Factory creates one object, and hence is probably best represented as a delegate in C#.) However, what the “keep instantiation quarantined” approach means is that the section on Abstract Factory use cases can be rewritten as:
Use: Any time you want to create an object that wasn’t instantiated by your auto-wiring of dependencies.
You’ll note that I didn’t say “that wasn’t instantiated by your IoC container”, that because calls to the container should be treated exactly the same way as calls to
new, which is why Windsor doesn’t give you a static method to access the container. Jeremy Miller emphasizes this too, even if StructureMap does have a static accessor. I’ve written some pretty bad code before today using that accessor…