Verify Your Guards With AutoFixture
An important tool in leveraging loosely-coupled components is using dependency injection (DI). A common and wide-spread approach to DI is using constructor injection. Basically, when using constructor injection, all dependencies are injected as parameters through your constructors. This allows strong-typed dependency declarations. It is good practice to follow the Guard Assertion pattern or Guard Clause pattern, like this:
- publicvoid Service(IService service1, IService service2)
- {
- if (service1 == null)
- {
- thrownewArgumentNullException("service1");
- }
- if (service2 == null)
- {
- thrownewArgumentNullException("service2");
- }
- }
These guard clauses makes sure that the injected dependencies are in a useful state.
For a long time I have been testing all my guard clauses through my unit tests. I’ve been having discussions with co-workers and associates about the necessity of testing guard clauses. Their argument is that by definition the CLR will throw the ArgumentNullException, it is part of the framework. My argument is that we cannot foresee how this code will be used or refactored in the future. So, to avoid a future situation where the injected dependencies are not verified, I’ll keep testing my guard clauses. Up until now I have done this like this:
- [Test]
- publicvoid Service1IsNullThrowsException()
- {
- Assert.Throws<ArgumentNullException>(() =>
- newService(null, _service2Mock));
- }
- [Test]
- publicvoid Service2IsNullThrowsException()
- {
- Assert.Throws<ArgumentNullException>(() =>
- newService(_service1Mock, null));
- }
For each of our constructors and each of their parameters I used to verify whether my guard clauses are in place. This is a very tedious and trivial task. Another pain of having these tests is that they are very brittle and will lead to a maintenance hell. I therefore had a chat with Mark Seemann at Danish Developers Conference 2013. He made an excellent session on writing maintainable unit tests. I asked him whether he was testing his guard clauses, and how he did that. His answer was that he was testing them, but got tired of writing tests for all permutations of these scenarios. He therefore implemented this functionality into AutoFixture, or more like into an extension. AutoFixture is an important, if not the most important, tool in my TDD toolbox. It keeps surprising me with new features, and new ways to optimize my TDD endeavors. Check out my recent post on AutoFixture.
AutoFixture has this very cool and, maybe, a little overseen extension called Idioms. It is an extension for idiomatic unit tests, that would be unit tests that keep using common templates. I have just realized this extension, and my first discovery is the GuardClauseAssertion class. This class can be used to test all constructors and all its parameters, to verify whether there is missing a guard clause in any of these. This is how my previous test methods would be replaced using the GuardClauseAssertion class:
- var fixture = newFixture();
- var assertion = newGuardClauseAssertion(fixture);
- assertion.Verify(typeof(Service).GetConstructors());
Using reflection all constructors and all their parameters are verified to make sure that guard clauses are in place. See, my maintenance hell just vanished. Awesome!
On a side-note, the Verify method will provide you with a quite detailed exception message if any constructor argument in any constructor is lacking a guard clause, like this:
Ploeh.AutoFixture.Idioms.GuardClauseException : An attempt was made to assign the value null to the parameter "service1" of the method ".ctor", and no Guard Clause prevented this. Are you missing a Guard Clause?
So, no more excuses not to set up guard clauses for your dependencies.
Tweetcomments powered by Disqus