How You Can Use AutoFixture To Test Your Guards Easily

Writing boring boilerplate test sucks.  When it comes to writing monotonous tests, I sometimes feel like I'd rather shoot myself in the foot just so I can get out of it.  This hatred of doing dull repetitive tasks generally means I'm constantly Googling to try and find better ways of working.  In today's tutorial, I'm going to share one of the biggest time-saving tips I use on my projects that help to eliminate this crap.  This article is a semi-follow-up from my article about recommending dependency injection techniques, available here.  

To quickly re-cap, use dependency injection, don't be a dingbat and use construction injection and when you use constructor injection, ensure you use a guard so you can guarantee that your class gest instantiated with everything it needs.  Now, if you follow this principle, then you'll write unit tests to ensure that your guards are working correctly.   The problem of writing unit tests for every combination of parameters for every class takes a long time and is TEDIOUS...  trust me.  Ok, so just to prove how boring writing this code is, based on this class for example: 

    public class MyClass
    {
        public MyClass(IDependency one, IDependency two)
        {
            CallGuard(one);
            CallGuard(two);
        }
    }
    

I would write three tests to ensure that all the guards work, these tests would look like this:

        [Test]
        public void  MyTest()
        {
          Assert.Throws( typeof(ArgumentNull Exception), new TestDelegate(null, null));
        }
        [Test]
        public void  MyTest1()
        {
          Assert.Throws( typeof(ArgumentNull Exception), new TestDelegate(object, null));
        }

        [Test]
        public void  MyTest1()
        {
          Assert.Throws( typeof(ArgumentNull Exception), new TestDelegate(null, object));
        }


Imagine working on a project with several thousand classes, imagine how boring it would be to write these guard tests for everything... one fateful day I bumped into a great library that makes life a lot less painful.  In today's article, I'm going to cover how to use that library to help reduce your guards... 

Introducing AutoFixture

AutoFixture is a great free library, written by Mark Seemann author of Dependency Injection within .NET. If you are new to dependency injection I recommend you check it out. Coincidentally, Mark's book was the book I read to learn dependency injection.  Autofixture has a number of cool features which I'll cover at a later date, but today I'm going to focus on how it simplifies our guard tests.

You can install Autofixture via Nuget. In this scenario we also want to install two additional packages:

As you can see from the screenshot above, in order to get the magic working you'll need to use:

  nuget install AutoFixture
  nuget install AutoFixture.AutoMoq
  nuget install AutoFixture.Idioms

Using AutoFixture

So how can we use Autoficture to reduce these boring tests, simple?  First, we create a helper method like so:

        public void EnsureConstructorArgumentsNotNull(Type type)
        {
            var fixture = new Fixture().Customize(new AutoMoqCustomization());
            var assertion = new GuardClauseAssertion(fixture);
            assertion.Verify(type.GetConstructors());
        }

We can now simplify our tests like so:

            ShouldNotAcceptNullConstructorArguments(typeof(MyClass));

Look how much quicker, simpler and easier it is now! With a one-liner, we can ensure that everything is passed into the constructor throws an argument if not present. Even though this snippet looks pretty simple, it really can save you and your team days' worth of effort on a larger project.

Important Note

If your guard, if you add in any custom exception name, the snippet above will fail.  Adding custom messages to your guards is a good idea.  To extend the code above to cater for this, you will need to write your own custom behavior expectation.  A behavior expectation is a way you can ensure your auto-guard checks work the way you need them to.  To allow the guard code to work, with my custom validation message, I created this custom behavior expectation within my unit test project:

    public class ArgumentNullBehaviorException : IBehaviorExpectation
    {
        public void Verify(IGuardClauseCommand command)
        {
            try
            {
                command.Execute((object)null);
            }
            catch (ArgumentNullException)
            {
                return;
            }

            throw new GuardClauseException();
        }
    }

I make the guard checking code work with your new behavior, you can pass it in, like this:

          var fixture = new Fixture().Customize(new AutoMoqCustomization());
            var argumentNullException = new ArgumentNullBehaviorException();
            var assertion = new GuardClauseAssertion(fixture, argumentNullException);
            assertion.Verify(type.GetConstructors());

Using this approach, you can still auto-test your guards, using whatever method you want. Enjoy!

submit to reddit

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

Back to top