-
Let's say I have something like this public sealed class AzuriteInfrastructure : IAsyncLifetime
{
private readonly AzuriteContainer container;
public AzuriteInfrastructure()
{
try
{
this.container = new AzuriteBuilder()
.WithCleanUp(true)
.Build();
}
catch
{
throw new TestClassException("Failed to create Azurite test container definition");
}
}
public Task InitializeAsync()
{
return this.container.StartAsync();
}
public async Task DisposeAsync()
{
await this.container.StopAsync();
await this.container.DisposeAsync();
}
}
[CollectionDefinition(Name)]
public class ApiTestCollection : ICollectionFixture<AzuriteInfrastructure>
{
public const string Name = nameof(ApiTestCollection);
}
public abstract class ApiTest(AzuriteInfrastructure azurite) : IAsyncLifetime
{
//....
}
[TestCollection(ApiTestCollection.Name)]
public sealed MyTestClass(AzuriteInfrastructure azurite) : ApiTest(azurite)
{
[Fact]
public async Task Does_assert_something()
{
//... uses the Azurite container
}
} Above code does spin up an Azurite container (using Testcontainers) once per test collection. How would you do this in TUnit? Note: Since xUnit 2.x does not support assembly fixtures, I basically have all tests in a custom test collection with that |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments
-
By searching the docs again I found https://thomhurst.github.io/TUnit/docs/comparison/framework-differences#assembly-level-hooks |
Beta Was this translation helpful? Give feedback.
-
You could do this: public static class AzuriteInfrastructure
{
public static AzuriteContainer Container { get; private set; }
[Before(Assembly)]
public static async Task Setup()
{
try
{
Container = new AzuriteBuilder()
.WithCleanUp(true)
.Build();
await Container.StartAsync();
}
catch
{
throw new TestClassException("Failed to create Azurite test container definition");
}
}
[After(Assembly)]
public static async Task TearDown()
{
await Container.StopAsync();
await Container.DisposeAsync();
}
}
public abstract class ApiTest
{
public AzuriteContainer Container => AzuriteInfrastructure.Container;
}
public sealed class MyTestClass : ApiTest
{
[Fact]
public async Task Does_assert_something()
{
//... uses the Azurite container
}
} |
Beta Was this translation helpful? Give feedback.
-
Or this: public sealed class AzuriteInfrastructure : IAsyncInitializer, IAsyncDisposable
{
private readonly AzuriteContainer container;
public AzuriteInfrastructure()
{
try
{
this.container = new AzuriteBuilder()
.WithCleanUp(true)
.Build();
}
catch
{
throw new TestClassException("Failed to create Azurite test container definition");
}
}
public Task InitializeAsync()
{
return this.container.StartAsync();
}
public async ValueTask DisposeAsync()
{
await this.container.StopAsync();
await this.container.DisposeAsync();
}
}
[ClassDataSource<AzuriteInfrastructure>(Shared = SharedType.Globally)]
public sealed class MyTestClass(AzuriteInfrastructure azurite) : ApiTest(azurite)
{
[Test]
public async Task Does_assert_something()
{
//... uses the Azurite container
}
} |
Beta Was this translation helpful? Give feedback.
-
@thomhurst Thanks for that quick answer! That seems pretty straight forward :) |
Beta Was this translation helpful? Give feedback.
Or this: