Skip to content

[Bug]: DisposeAsync() ordering since 1.21.0 #5336

Closed

Description

@AlexandreBossard

Description

We have multilevel Nested property injection (at least 3) that all implement IAsyncInitializer and IAsyncDisposable. While upgrading to the latest version, we noticed that our test fixtures were failing during tearing down. We assumed that the DisposeAsync() were called in the reverse order of the InitialzeAsync(), but since v1.21.0 it seems this is not true anymore.

This breaks our fixture isolation that do do some setup/teardown of resources (mostly database & seeding) that have to be in that predictable order.

We would like to know if this a regression ? Otherwise can it be a feature, as it seems to be sane way to handle Nested initialization

Expected Behavior

DisposeAsync() to be called in reverse order of InitializeAsync() when nested properties initialization are used.

Actual Behavior

DisposeAsync() seems to be called in an arbitrary order.

Steps to Reproduce

using TUnit.Core.Interfaces;

namespace Playground;

public sealed class AppSeedFixture : IAsyncInitializer, IAsyncDisposable
{
    [ClassDataSource<ContextFactoryFixture>(Shared = SharedType.PerTestSession)]
    public required ContextFactoryFixture ContextFactoryFixture { get; init; }

    public ValueTask DisposeAsync()
    {
        Console.WriteLine("Dispose {0}", GetType().Name);
        return ValueTask.CompletedTask;
    }

    public Task InitializeAsync()
    {
        Console.WriteLine("Init {0}", GetType().Name);
        return Task.CompletedTask;
    }
}

public sealed class ContextFactoryFixture : IAsyncInitializer, IAsyncDisposable
{
    public ValueTask DisposeAsync()
    {
        Console.WriteLine("Dispose {0}", GetType().Name);
        return ValueTask.CompletedTask;
    }

    public Task InitializeAsync()
    {
        Console.WriteLine("Init {0}", GetType().Name);
        return Task.CompletedTask;
    }
}

public sealed class AppServiceFixture : IAsyncInitializer, IAsyncDisposable
{
    [ClassDataSource<AppSeedFixture>(Shared = SharedType.PerTestSession)]
    public required AppSeedFixture AppSeedFixture { get; init; }

    public ValueTask DisposeAsync()
    {
        Console.WriteLine("Dispose {0}", GetType().Name);
        return ValueTask.CompletedTask;
    }

    public Task InitializeAsync()
    {
        Console.WriteLine("Init {0}", GetType().Name);
        return Task.CompletedTask;
    }
}

public class SandboxTests
{
    [ClassDataSource<AppServiceFixture>(Shared = SharedType.PerTestSession)]
    public required AppServiceFixture AppServiceFixture { get; init; }

    [Test]
    public async Task Test1()
    {
        await Assert.That(0 == 0).IsTrue();
    }
}

outputs in 1.21.0

passed Test1 (4ms)
  Standard output
    Init ContextFactoryFixture
    Init AppSeedFixture
    Init AppServiceFixture
    Dispose ContextFactoryFixture
    Dispose AppSeedFixture
    Dispose AppServiceFixture

output in 1.20.0

passed Test1 (5ms)
  Standard output
    Init ContextFactoryFixture
    Init AppSeedFixture
    Init AppServiceFixture
    Dispose AppServiceFixture
    Dispose AppSeedFixture
    Dispose ContextFactoryFixture
    
  Error output

TUnit Version

1.21.24

.NET Version

.Net 10

Operating System

macOS

IDE / Test Runner

dotnet CLI (dotnet test / dotnet run)

Error Output / Stack Trace

Additional Context

No response

IDE-Specific Issue?

  • I've confirmed this issue occurs when running via dotnet test or dotnet run, not just in my IDE

Activity

  1. changed the title [-][Bug]: DisposeAsync() ordering since 1.20.0[/-] [+][Bug]: DisposeAsync() ordering since 1.21.0[/+] on Apr 1, 2026
  2. jeremad commented on Apr 1, 2026

    @jeremad

    https://github.com/thomhurst/TUnit/pull/5213/files#diff-809088b394fd911cb5c4584464dd6fbfef50d4455c67e10f545d038c77853e9eR117

    In my understanding, changing OrderByDescending to OrderByAscending should fix the issue

  3. thomhurst commented on Apr 1, 2026

    @thomhurst
    Owner

    Should be fixed in the latest!

  4. jeremad commented on Apr 2, 2026

    @jeremad

    Fixed indeed! thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't working

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions