So you are working on a BIG project and you discover that writing unit-tests is really a pain. Why? Because once you want to create a new test, you find out that the class you want to test has got a lot of dependencies to other classes, which you do not want to be bothered with right now.
If you ever encounter this problem, you have actually encountered a big code-smell. Code smells are bad, very bad, because it means the whole implementation of the system and maybe even the whole system design is bad. And if you cannot easily write unit-test for the code-base than your code-base will be legacy code in no time.
There is a lot of self reference in the above paragraphs by the way, because legacy code, by the name of it, is code that does not (yet) have unit tests. And if you want to create unit tests (real unit tests: against just a tiny bit of code) as opposed to integration tests (which are written against alot of classes, and undoubtedly will run much slower) you really need a loosely coupled design.
Instead of writing a whole new blog about this, let me share some links I found about this on the ‘net.
First of all I want you to have a look at Singletons are pathological liars, because that is one of the challenges we currently have in our own code base as all our repositories are written as singletons. But better, the author of that article, Misko Hevery, has since he wrote that article created a bunch of really good presentations for the Google Tech Talks. Have a look at the OO Design for Testability presentation of Misko Hevery.
What the presentation makes very clear is to have your business classes depened on interfaces instead of concrete classes. This is all about a loosely coupled design and the Hollywood Principle (don’t call us, we’ll call you!), which is all very nicely explained in the great book by Head First, Design Patterns.
Anyway, once you get into this deeper, you will find that there are almost two camps on the net.
One camp telling you to have the most of the dependencies that classes need in the constructors of those classes
- Automated testing patters and smells (video) by Gerard Meszaros. Author of the xUnit Test Patterns book gives a technical presentation about how to write good unit-tests.
- OO Design for Testability presentation of Misko Hevery (video). pleads for writing against interfaces instead of hardwiring your objects and is clearly not in favour of using a service locator to get hold on all the dependencies of a class that does business logic.
- What is all the fuss about IoC containers (Service locators) An overall explanation of what the fuss is all about.
- Prefer dependency injection over service locators Steven Harman is practical and in his blog boils it down to what it is about: writing solid unittests instead of integration tests.
- Why do I need a service locator as opposed to simply Dependency Injection? A thread on stackoverflow asking the question if there really are two camps or not.
- Tame your software dependencies for more flexible apps James Kovacs is explaining why a service locator (Registry, IoC Container) might be usefull. Download the example C# projects where he shows five different projects. From the first project that does not even use interfaces upto the fifth that uses a Service Locator.
- Zen and the art of Castle maintenance Reaction of Hamett on Kovacs article. Windsor Castle being a tool for a service locator.
- What are the pro’s and cons for using a IoC container?
- Optional dependencies and primal dependencies A good article for distinguish between necessary dependencies and those dependencies that might only be needed in some places of the class.
It would be best to remain pragmatic about all the stuff that you will encounter on the above links though. The ideas are to have the best of both worlds. Those both worlds are ease of producing production code and ease of maintenance finding and fixing bugs by having and creating necessary unit-tests.
- the other camp leaning towards the other side telling you to have service locators which will automatically get you all the depended instances of the classes you need. With or without configuration files.
The following articles will be very helpful to read more on this topic as well: