Skip to main content

Injectable Class Data Source

The ClassDataSource attribute is used to instantiate and inject in new classes as parameters to your tests and/or test classes.

The attribute takes a generic type argument, which is the type of data you want to inject into your test.

It also takes an optional Shared argument, controlling whether you want to share the instance among other tests. This could be useful for times where it's very intensive to spin up lots of objects, and you instead want to share that same instance across many tests.

Ideally don't manipulate the state of this object within your tests if your object is shared. Because of concurrency, it's impossible to know which test will run in which order, and so your tests could become flaky and undeterministic.

Options are:

Shared = SharedType.None

The instance is not shared ever. A new one will be created for you.

Shared = SharedType.Globally

The instance is shared globally for every test that also uses this setting, meaning it'll always be the same instance.

Shared = SharedType.ForClass

The instance is shared for every test in the same class as itself, that also has this setting.

Shared = SharedType.Keyed

When using this, you must also populate the Key argument on the attribute.

The instance is shared for every test that also has this setting, and also uses the same key.

Initialization and TearDown

If you need to do some initialization or teardown for when this object is created/disposed, simply implement the IAsyncInitializer and/or IAsyncDisposable interfaces

Example

public class MyTestClass
{
[Test]
[ClassDataSource<WebApplicationFactory>(Shared = SharedType.Globally)]
public void MyTest(WebApplicationFactory webApplicationFactory)
{
}

public record WebApplicationFactory : IAsyncInitializer, IAsyncDisposable
{
// Some properties/methods/whatever!

public Task InitializeAsync()
{
await StartServer();
}

public ValueTask DisposeAsync()
{
await StopServer();
}
}
}

Class Data Source Overloads

If you are using an overload that supports injecting multiple classes at once (e.g. ClassDataSource<T1, T2, T3>) then you should specify multiple SharedTypes in an array and keys where applicable.

E.g.

[Test]
[ClassDataSource<Value1, Value2, Value3, Value4, Value5>
(
Shared = [SharedType.Globally, SharedType.Keyed, SharedType.ForClass, SharedType.Keyed, SharedType.None],
Keys = [ "Value2Key", "Value4Key" ]
)]
public class MyType(Value1 value1, Value2 value2, Value3 value3, Value4 value4, Value5 value5)
{

}