Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions docs/docs/test-authoring/nested-data-sources.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This typically leads to complex setup code with manual initialization chains.

## The Solution

TUnit automatically initializes nested data sources in the correct order using the `[DataSourceGeneratorProperty]` attribute.
TUnit automatically initializes nested data sources in the correct order using any data source attribute that implements `IDataSourceAttribute` (such as `[ClassDataSource<T>]`).

## Basic Example

Expand Down Expand Up @@ -61,7 +61,7 @@ public class TestApplication : IAsyncInitializer, IAsyncDisposable
private WebApplicationFactory<Program>? _factory;

// This property will be initialized BEFORE InitializeAsync is called
[DataSourceGeneratorProperty<RedisTestContainer>]
[ClassDataSource<RedisTestContainer>]
public required RedisTestContainer Redis { get; init; }

public HttpClient Client { get; private set; } = null!;
Expand Down Expand Up @@ -135,13 +135,13 @@ public class CompleteTestEnvironment : IAsyncInitializer, IAsyncDisposable
private WebApplicationFactory<Program>? _factory;

// All of these will be initialized before InitializeAsync
[DataSourceGeneratorProperty<RedisTestContainer>]
[ClassDataSource<RedisTestContainer>]
public required RedisTestContainer Redis { get; init; }

[DataSourceGeneratorProperty<PostgresTestContainer>]
[ClassDataSource<PostgresTestContainer>]
public required PostgresTestContainer Database { get; init; }

[DataSourceGeneratorProperty<LocalStackContainer>]
[ClassDataSource<LocalStackContainer>]
public required LocalStackContainer LocalStack { get; init; }

public HttpClient Client { get; private set; } = null!;
Expand Down Expand Up @@ -210,7 +210,7 @@ You can also use async data source generators that depend on initialized resourc
public class UserTestDataAttribute : AsyncDataSourceGeneratorAttribute<UserTestData>
{
// This will be initialized first
[DataSourceGeneratorProperty<TestApplication>]
[ClassDataSource<TestApplication>]
public required TestApplication App { get; init; }

public override async IAsyncEnumerable<UserTestData> GenerateDataSourcesAsync(
Expand Down Expand Up @@ -245,15 +245,15 @@ public class UserTestDataAttribute : AsyncDataSourceGeneratorAttribute<UserTestD

## How It Works

1. TUnit detects properties marked with `[DataSourceGeneratorProperty]`
1. TUnit detects properties marked with data source attributes (like `[ClassDataSource<T>]`)
2. It builds a dependency graph and initializes in the correct order
3. Each object's `InitializeAsync` is called after its dependencies are ready
4. Disposal happens in reverse order automatically

## Best Practices

1. **Implement IAsyncInitializer**: For any class that needs async initialization
2. **Use DataSourceGeneratorProperty**: To declare dependencies that must be initialized first
2. **Use Data Source Attributes**: Use attributes like `[ClassDataSource<T>]` to declare dependencies that must be initialized first
3. **Share Expensive Resources**: Use `SharedType` attributes to avoid creating multiple containers
4. **Dispose Properly**: Implement `IAsyncDisposable` for cleanup
5. **Keep Initialization Fast**: Do only essential setup in `InitializeAsync`
Expand Down
8 changes: 4 additions & 4 deletions docs/examples/nested-data-sources-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ public class TestApplication : IAsyncInitializer, IAsyncDisposable
private WebApplicationFactory<Program>? _factory;

// These properties will be initialized by TUnit before InitializeAsync is called
[DataSourceGeneratorProperty<RedisTestContainer>]
[ClassDataSource<RedisTestContainer>]
public required RedisTestContainer Redis { get; init; }

[DataSourceGeneratorProperty<SqlServerTestContainer>]
[ClassDataSource<SqlServerTestContainer>]
public required SqlServerTestContainer SqlServer { get; init; }

public HttpClient Client { get; private set; } = null!;
Expand Down Expand Up @@ -253,7 +253,7 @@ public class UserApiIntegrationTests
// Data source that provides test scenarios with pre-populated data
public class OrderTestScenarioAttribute : AsyncDataSourceGeneratorAttribute<OrderTestScenario>
{
[DataSourceGeneratorProperty<TestApplication>]
[ClassDataSource<TestApplication>]
public required TestApplication App { get; init; }

public override async IAsyncEnumerable<OrderTestScenario> GenerateDataSourcesAsync(DataGeneratorMetadata metadata)
Expand Down Expand Up @@ -397,7 +397,7 @@ public class OrderProcessingTests

1. **Use IAsyncInitializer**: Implement this interface for any class that needs async initialization.

2. **Declare Dependencies**: Use `[DataSourceGeneratorProperty]` to declare dependencies that need to be initialized first.
2. **Declare Dependencies**: Use data source attributes like `[ClassDataSource<T>]` to declare dependencies that need to be initialized first.

3. **Share Expensive Resources**: Use `SharedType.PerClass` or `SharedType.Keyed` for resources that are expensive to create.

Expand Down
10 changes: 5 additions & 5 deletions docs/examples/nested-data-sources-quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class TestApp : IAsyncInitializer, IAsyncDisposable
private WebApplicationFactory<Program>? _factory;

// This property will be initialized before InitializeAsync is called
[DataSourceGeneratorProperty<RedisFixture>]
[ClassDataSource<RedisFixture>]
public required RedisFixture Redis { get; init; }

public HttpClient Client { get; private set; } = null!;
Expand Down Expand Up @@ -90,13 +90,13 @@ public class FullTestApp : IAsyncInitializer, IAsyncDisposable
private WebApplicationFactory<Program>? _factory;

// All these will be initialized before InitializeAsync
[DataSourceGeneratorProperty<RedisFixture>]
[ClassDataSource<RedisFixture>]
public required RedisFixture Redis { get; init; }

[DataSourceGeneratorProperty<PostgresFixture>]
[ClassDataSource<PostgresFixture>]
public required PostgresFixture Postgres { get; init; }

[DataSourceGeneratorProperty<RabbitMqFixture>]
[ClassDataSource<RabbitMqFixture>]
public required RabbitMqFixture RabbitMq { get; init; }

public HttpClient Client { get; private set; } = null!;
Expand Down Expand Up @@ -139,7 +139,7 @@ public class FullTestApp : IAsyncInitializer, IAsyncDisposable

## Key Points

✅ **Automatic Initialization**: Properties marked with `[DataSourceGeneratorProperty]` are initialized before `InitializeAsync` is called
✅ **Automatic Initialization**: Properties marked with data source attributes (like `[ClassDataSource<T>]`) are initialized before `InitializeAsync` is called

✅ **Proper Order**: TUnit handles the dependency graph and initializes in the correct order

Expand Down