If you have ever worked on a large project using TDD, or, you have worked on a project that had a high-quality gate, you will appreciate all the time and effort it takes to write the test set-up code. In some instances, on complex classes, the set-up code alone took well over 100 lines of code to write before I could crack on with the actual tests themselves. In general, if you find that your unit test classes are going down the same route, it is likely that you are structuring your tests sub-optimally. No matter how well written your classes are, some form of test setup will always be needed. If you have a class that has several other dependencies injected into it, before you know it, it can take more time to write your Moq set-up methods than it does your actual test code 😢
On most projects, a large part of the set-up code is consumed by assigning default values to mocked objects. This data then allows for assertions to be made within the test later on. How else can you test that a certain component works, without comparing an expecting value to something?
On a normal project, things get even more frustrating as time passes. Code is not static, neither is life. Requirements change, your code will need to be updated and refactored to reflect these changes. Simply changing the constructor signature, or adding a new dependency on a class, can result in a lot of test code refactoring. I have wasted an entire morning, going through the broken unit test set-up code and patching things up. If you're in a rush due to a deadline, this unit test set-up code can start to rot quickly. Test code can start to smell pretty bad, pretty quickly 🦨🦨🦨
If you are anything like me, you will prefer focusing your time and energy on writing new and interesting features, rather than writing boring boilerplate code and refactoring old unit tests. Any tool or framework that can reduce the amount of tedious set-up code that I have to write makes me happy. This is where AutoFixture comes in. If you want to cut down on the amount of set-up code you have to write and maintain, then read on.
What Is Autofixture?
AutoFixture really is a game-changer when it comes to simplifying your unit test code. Autofixture can be thought of as a framework that will automatically pre-populate your classes, interfaces and data types with test data, all without you needing to write the code yourself... Auto Fakes on steroids!!!! Below shows a very simple example of how to use AutoFixture:
Pre-populating primitive data types is useful but not that exciting. What is more exciting about Autofixture is the ability to completely generate whole objects worth of test data. Take this simple class:
You could use this code to completely populate this object with test data:
If you have written a lot of unit tests within your life, you can appreciate the amount of time it takes to simply write the code to pre-populate an object with some fake dummy data. Using Autofixture means you can literally use one line and get a fully populated object, instead of having to write a crapload of manual set-up code ❤️❤️❤️.
Using Autofixture in combination with something like Resharper means you can change and refactor your classes with a click of a button. In most instances, your unit tests will also update automatically and continue to run and pass OK. All this benefit without you needing to go back in and fix broken tests! The tests will automatically reflect your class changes and the data will automatically be re-generated so it passes... it really is a game-changer!
How To Install Autofixture?
Autofixture is free to use and easy to install via NuGet. There are a number of different associated packages for Autofixture depending on what IoC container you use. These additional packages cover everything from the test suite you're using, like NUnit, xUnit add-on, to what mocking framework you're using like Moq, RhinoMocks etc..
Using NUnit and Moq as an example, simply add in the packages relevant to the project and you're ready to rock ♡ ♥💕❤😘
Wait -There's More To Autofixture
On top of auto-populated objects, you can also use Autofixture to help automate your tests. If you use dependency injection with guards, you can create a simple helper method to automatically check for nulls parameter values for you! This will further minimize the amount of test code you need to write. Read here for more information on how to do that. You can also further reduce your AutoFixture code above by auto-inserting pre-populated test data into your tests like so:
Using this technique means that within our unit tests we only need to worry about the actual logic and leave the arrange part to Autofixture. Offloading the arrange config, greatly reduces the amount of unit test maintenance that needs to be done.
NOTE: If like me, you use Moq and NUnit, if you try and run the code above you may get this error:
AutoData error - No arguments were provided
To get AutoData working in this scenario, you need to jump through a few more hoops, which is covered in this tutorial.
If you write a lot of tests, I'm hoping you can appreciate how much time AutoFixture can save you. Pre-AutoFixture, the amount of boilerplate test set-up code was maybe 15-20% more. Updating the test code to work with the new code changes often took longer than making the change. This problem is now largely solved with AutoFixture
Using Autofixture will greatly simplify your codebase and consequently make unit test maintenance easier to manage. If you're not using Autofixture, then my challenge to you is to add it to your project now. I bet that within 30 minutes, you'll be able to make at least one of your test classes simpler, easier to read and a lot easier to maintain in the future. Happy Coding 🤘