2 Reasons Why Every Test Should Start With Autofixture


Writing unit tests can be a real pain.

You often have to write the setup code repeatedly, which can be a nightmare to maintain in the long run. However, what if you could set up your test data automatically? Well, with Autofixture, you can.

Autofixture is a .NET library that helps you to write unit tests by automating the process of creating and registering fake objects. In addition, it improves the maintainability of your unit tests by improving Arrange phase of your unit tests.

In this post, we will be looking at what makes this library so remarkable and how you can use it to save time while testing.

What is AutoFixture?

Although the benefits of unit testing your code cannot be overstated, it is still easy to admit that setting up and maintaining your dummy data can lead to a headache. This hassle is one of the core reasons Mark Seemann’s AutoFixture quickly shot up to become one of the most popular open-source .NET testing libraries, with over 2,600 GitHub stars.

AutoFixture is an open-source testing library that can help you write sustainable unit tests quickly. To achieve the level of speed that AutoFixture promises, it removes the need for setting up test data manually in the arrange phase of your test method. By doing so, developers can focus on the sections of their unit tests that matter, allowing them to build new test cases quickly.

How to install AutoFixture?

The easiest way to install AutoFixture is by grabbing the package manager from NuGet. You can either do it through the CLI or your IDE’s package manager:

Installing With the .NET CLI:

> dotnet add package AutoFixture

Installing With Your Package Manager:

PM > Install-Package AutoFixture

Two reasons to use Autofixture

Why use Autofixture? Well, there are two main benefits of using it.

#1 You can focus on the parts of the unit tests that matter

While checking the code logic should be the core goal of testing, many developers often spend too much time setting up test methods. In some cases, you spend more time creating random test data than testing the actual scenario. However, some of the fixture data is worthless and will not directly influence the test case’s output.

This laborious process can make unit testing feel like a chore rather than a task you should enjoy. If you start spending too much time writing unit tests, you will soon start skipping them. And only write an integration test here and there.

Fortunately, AutoFixture reduces the need to manually set up and maintain this data for you by aiding in creating anonymous variables. When you use the AutoFixture library, it will generate your desired value of any type. You may then use this value in your test case at will, saving you the time it will take to hand-code it.

#2 Refactor-safe testing

One of the primary goals of the AutoFixture library is to remove the need for manually creating anonymous variables each time you set up a fixture for a test. While this mainly allows you to write swift test cases, covering every aspect of your code, it is also beneficial for maintenance. Essentially, AutoFixture is refactor-safe, which means any changes to the classes you use for dummy data will not affect your tests.

For example, take a look at the following class:

public class AddressDetails
{
    public AddressDetails(string name,
                            string homeAddress,
                            string country,
                            string email,
                            string fileLocation)
    {
        Name = name;
        HomeAddress = homeAddress;
        Country = country;
        Email = email;
        FileLocation = fileLocation;
    }

    public string Name { get; set; }
    public string HomeAddress { get; set; }
    public string Country { get; set; }
    public string Email { get; set; }
    public string FileLocation { get; set; }
}

Every time you add a new property or rename an existing one, you need to update your tests. Making the changes can be heavily time-consuming, especially if you used that property in multiple test cases.

Sure, Visual Studio can assist you, but you still need to check the changes in the test suite.

On the other hand, you don’t need to change the tests when you create anonymous variables with Autofixture. Later in the code examples, you will see how easily you can create a fake instance of your classes.

How to use AutoFixture – code examples

You can use AutoFixture for an extensive range of test scenarios. For example, you can use it for string and number generation, crafting complex types, etc. For all examples here, I will assume that you have already created a Fixture instance:

Fixture fixture = new Fixture();

This is a base class for generating anonymous test data.

String Generation

Strings are a necessary part of every code, and you often use them when writing unit tests. However, coming up with unique, complex strings can still be time-consuming, especially if you need to create several strings. Fortunately, this is a breeze when using AutoFixture.

Syntax:

var automaticString = fixture.Create<string>();

Sample Result:

"d4agh2a0-b787-401d-90a3-b267x7dbed0a7"

In this example, you create a variable called automaticString, which you use to store the generated string. Then, using the fixture instance, you can call Create, passing it a string data type. This construct tells AutoFixture to generate a random string value.

Number Generation

Generating numbers is another aspect of testing that you often repeat when creating our unit tests. Luckily, AutoFixture has included the ability to automatically generate numbers.

Syntax:

var automaticNumber = fixture.Create<int>();

Sample Result

> 56

When automatically generating numbers for our test cases, AutoFixture will always use random numbers. Naturally, this non-specific way of creating new numbers means that you can get a wide array of digits to use in your test scenario. So, if you run this test a few more times, you may get the following results:

> 24

> 95

> 42

AutoFixture also allows you to apply a custom range for creating numbers, allowing for more flexible test cases.

Complex Type Generation

Classes act as one of the core building blocks of powerful .NET programs. These data types allow developers to add primitive properties to their payload, allowing you to bundle similar details together in one structure.

AutoFixture can create a new instance of any class. Every property gets a random value. For example, let’s create an instance of the AddressDetails class, which was shown earlier in the article.

Syntax:

var details = fixture.Create<AddressDetails>();

Sample Result:

Abstract Types

AutoFixture also accounts for handling test cases of classes that do not have constructors. In such cases, you may use the library’s Register method instead. This method allows you to identify a custom function that will help craft the desired object:

Syntax:

fixture.Register<IMyInterface>(() => new FakeInterfaceImplementation());

In this case, each time we ask our code to register a new instance of IMyInterface, the fixture instance will return a new instance of FakeInterfaceImplementation instead.

A Sequence of Strings

You may also use AutoFixture to create a sequence of strings rather than a single string value by using the CreateMany method. The result of this method creates an IEnumerable<string>:

Syntax:

var myStrings = fixture.CreateMany<string>();

Sample Result:

> string: "d4agh2a0-b787-401d-90a3-b267d7dbed0a7"

> string: "ce70a7b-fae5-474f-8055-415ca46eac20"

> string: "79b45532-d66f-4abc-9311-77ba68dc9e3c"

You can clearly see the benefit of the CreateMany. You can generate multiple values in a single line of code. Without AutoFixture, the simplest way to do this will be by using a for-loop or writing a string value declaration on each line, which will be time-consuming if you need several string values.

A Sequence of Custom Objects

In addition to string values, AutoFixture also allows you to extend the power of CreateMany by using it to fabricate custom objects. Essentially, you can use CreateMany to produce sequences of any type you want. This method will generate an IEnumerable, which stores your desired value type.

Syntax:

fixture.RepeatCount = 4;
var manyDetails = fixture.CreateMany<AddressDetails>()

By setting up the RepeatCount, you can specify how many instances you want in the list.

Sample Result:

The ability to create many instances in a single line of code is a dream for unit testing.

It is one of the features that make AutoFixture stand ahead of its peers. This feature allows you to dive straight into the core logic of unit tests rather than wasting time setting up new instances for every test case you create.

Conclusion

Mark Seemann’s AutoFixture library is a true gamechanger when you need to write brief and concise unit tests.

This tool can especially be useful for quickly writing tests for .NET developers who focus on Test Driven Development (TDD).

Don’t hesitate to install this library if you have been struggling to maintain your test code or create unique fixtures for your test cases.

And if you want to learn more about how to write effective C# code using TDD, be sure to read the comprehensive article on the topic.

Recent Posts