Anonymous test data with AutoFixture

Often times we have unit or integration tests that rely on some input data. The easiest solution is just to take some hard-coded values and move on with life. This has some major downsides:

Giving specific values in a test carries meaning, but we are often times not interested in that. We just need to pass the object around to fulfill the API. Also, the simplest solution to fulfill your test is literally checking against those values.

Here is an elegant solution to that problem: AutoFixture. I will show you what it can do, especially in combination with xUnit.

AutoFixture:

Write maintainable unit tests, faster. AutoFixture makes it easier for developers to do Test-Driven Development by automating non-relevant Test Fixture Setup, allowing the Test Developer to focus on the essentials of each test case.

You can check on the given website how to setup a test, which uses AutoFixture. I want to show you something else. The magic and power of data-driven tests in combination with AutoFixture. The neat thing is, that for all the major testing frameworks, there is an extension, which makes it super trivial to write those tests. My all-time favorite testing framework is xUnit. So to get the magic, we have to install this nuget package: AutoFixture.Xunit. Or just simply:

dotnet add package AutoFixture.Xunit

The first test

For the whole magic, we can use the AutoData attribute like this:

[Theory]
[AutoData]
public void TestOne(string name)
{
    var sut = new MyFooService();

    var result = sut.MyCall(name);

    Assert.NotNull(result);
}

As you can see, we never specified name but still it is working. And here we can see what the output of name is:

name

With all of the modern testing framework, we can write data-driven tests. But this can mean that on one row a date is important whereas on another it isn't anymore. And also here the package got you covered. In the fashion of InlineData, which is native to xUnit, the AutoFixture package introduces AutoInlineData where we can set 0 to all parameters at will.

[Theory]
[InlineAutoData]
[InlineAutoData(31)]
[InlineAutoData(31, "Steven")]
public void TestTwo(int age, string name)
{
    var sut = new MyFooService();

    var result = sut.MyCall(name, age);

    Assert.NotNull(result);
}

name2

With AutoFixture in general you could also create automatically complete classes if you want:

[Theory]
[InlineAutoData]
public void TestThree(string name, MyFooService sut)
{
    var result = sut.MyCall(name);
    
    Assert.NotNull(result);
}

Conclusion

With AutoFixture and the power of xUnit (or nUnit / MSTest) you can have tests, which are more robust, simple, and the stuff which should carry meaning, does it!

Resources

  • Source code to this blog post: here
  • All my sample code is hosted in this repository: here

How to unit test a RavenDB

RavenDB is a well known open-source document-oriented databse for .NET. And of course we want to test our logic and not only locally while developing, but also our continuous integration pipeline should be able to run our tests. So let's tackle exactly that.

A better enumeration - Type safe from start to end

Enumerations are one of the fundamental value types in C#. enum's are handy if you have a constrained set of allowed values. But the enum type also has a lot of drawbacks. Personally, one major issue for me is that you can't define methods inside the enum. Plus, you can just pass them invalid values and it just works (Todd Howard I'm looking at you).

So why not make a lightweight alternative which removes a lot of the shortcomings of an enum?

Tutorial Unit and E2E Testing in Blazor - Part 1

This blog post should give you an easy and good introduction how to unit and end-to-end test your Blazor Application. Furthermore it does not matter if we are running server side or client side aka WebAssembly. The main two libraries we are using is first bUnit for unit-testing and Playwright for end-to-end testing. So let's dive in!

An error has occurred. This application may no longer respond until reloaded. Reload x