---
title: "Typesafety in xUnit with TheoryData<T>"
description: "I recently discovered this small but very useful utility in xUnit: `TheoryData<T>`."
updated: 2024-03-05
tags: [".NET", "C#", "xUnit"]
canonical: "https://steven-giesel.com/blogPost/a8aa3385-8829-444a-b269-7ecb38aeaf2f/typesafety-in-xunit-with-theorydatat"
---

# Typesafety in xUnit with TheoryData<T>

I recently discovered this small but very useful utility in xUnit: `TheoryData<T>`.

## The problem
I had the following code in my repository:
```csharp
public static IEnumerable<object[]> Data => new List<object[]>
    {
        new object[] { new Action<IServiceCollection>(services => services.UseSqliteAsStorageProvider()) },
        new object[] { new Action<IServiceCollection>(services => services.UseSqlAsStorageProvider()) },
        new object[] { new Action<IServiceCollection>(services => services.UseInMemoryAsStorageProvider()) },
        new object[] { new Action<IServiceCollection>(services => services.UseRavenDbAsStorageProvider()) },
        new object[] { new Action<IServiceCollection>(services => services.UseMySqlAsStorageProvider()) },
    };

[Theory]
[MemberData(nameof(Data))]
public void GivenAlreadyRegisteredRepository_WhenTryingToAddAnotherStorage_ThenException(Action<IServiceCollection> act)
```

The issue her eis that `Data` is of type `IEnumerable<object[]>` and the `act` parameter is of type `Action<IServiceCollection>`. This means that I can pass anything to the method and the compiler will happily accept it. Here is where the `TheoryData<T>` comes in.

## The solution
`TheoryData<T>` is a class that allows to wrap the data in a strongly typed way. Here is how I used it:
```csharp
public static TheoryData<Action<IServiceCollection>> Data => new() 
{
    services => services.UseSqliteAsStorageProvider(),
    services => services.UseSqlAsStorageProvider(),
    services => services.UseInMemoryAsStorageProvider(),
    services => services.UseRavenDbAsStorageProvider(),
    services => services.UseMySqlAsStorageProvider()
};

[Theory]
[MemberData(nameof(Data))]
public void GivenAlreadyRegisteredRepository_WhenTryingToAddAnotherStorage_ThenException(Action<IServiceCollection> act)
```

Exactly the same test, but way more typesafe. Now the compiler will not allow me to pass anything other than `Action<IServiceCollection>` to the method.