Xunit.DependencyInjection 11.3.2

Xunit.DependencyInjection

Xunit.DependencyInjection NuGet Ask DeepWiki

Use Microsoft.Extensions.DependencyInjection to resolve xUnit test cases: constructor-inject services into your test classes instead of writing them by hand, and reuse the same Startup/host configuration you use in your application.

xUnit v2 users: please use the v2 branch.

Xunit.DependencyInjection.SkippableFact is obsolete on xunit.v3 and no longer needed.

Getting started

Install the NuGet package:

dotnet add package Xunit.DependencyInjection

Add a Startup class to your test project and register your services in ConfigureServices:

namespace Your.Test.Project
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<IDependency, DependencyClass>();
        }
    }
}

Then inject IDependency into your test class constructor, exactly like you would with any other DI-enabled class:

public interface IDependency
{
    int Value { get; }
}

internal class DependencyClass : IDependency
{
    public int Value => 1;
}

public class MyAwesomeTests
{
    private readonly IDependency _d;

    public MyAwesomeTests(IDependency d) => _d = d;

    [Fact]
    public void AssertThatWeDoStuff()
    {
        Assert.Equal(1, _d.Value);
    }
}

Xunit.DependencyInjection builds on top of the generic host and fully supports its lifecycle, so you can use any feature the generic host offers, including (but not limited to) IHostedService.

Integrating with ASP.NET Core TestHost (3.0+)

With an ASP.NET Core Startup class

dotnet add package Microsoft.AspNetCore.TestHost
public class Startup
{
    public void ConfigureHost(IHostBuilder hostBuilder) => hostBuilder
        .ConfigureWebHost[Defaults](webHostBuilder => webHostBuilder
        .UseTestServer(options => options.PreserveExecutionContext = true)
        .UseStartup<AspNetCoreStartup>());
}

With Minimal APIs

If your web project uses Minimal APIs instead of an ASP.NET Core Startup class, install Xunit.DependencyInjection.AspNetCoreTesting:

dotnet add package Xunit.DependencyInjection.AspNetCoreTesting
public class Startup
{
    public IHostBuilder CreateHostBuilder() => MinimalApiHostBuilderFactory.GetHostBuilder<Program>();
}

Your ASP.NET Core project may need to add InternalsVisibleTo for the test project, or add public partial class Program { } at the end of Program.cs, so the test project can reference Program.

See Xunit.DependencyInjection.Test.AspNetCore for a full example.

Startup configuration styles

Startup supports two configuration styles. The Configure method (see Initializing data on startup) is supported by both styles.

HostApplicationBuilder style

  • CreateHostApplicationBuilder method

    If this method is not found, the host falls back to Host.CreateEmptyApplicationBuilder(new() { ApplicationName = assemblyName.Name }).

    public HostApplicationBuilder CreateHostApplicationBuilder([AssemblyName assemblyName]) { }
    
  • ConfigureHostApplicationBuilder method (presence of this method selects the HostApplicationBuilder style)

    public void ConfigureHostApplicationBuilder(IHostApplicationBuilder hostApplicationBuilder) { }
    
  • BuildHostApplicationBuilder method

    If this method is not found, the host is built by simply calling hostApplicationBuilder.Build().

    public IHost BuildHostApplicationBuilder(HostApplicationBuilder hostApplicationBuilder)
    {
        return hostApplicationBuilder.Build();
    }
    

Startup/HostBuilder style

  • CreateHostBuilder method

    public class Startup
    {
        public IHostBuilder CreateHostBuilder([AssemblyName assemblyName]) { }
    }
    
  • ConfigureHost method

    public class Startup
    {
        public void ConfigureHost(IHostBuilder hostBuilder) { }
    }
    
  • ConfigureServices method

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services[, HostBuilderContext context]) { }
    }
    
  • BuildHost method

    If this method is not found, the host is built by simply calling hostBuilder.Build().

    public class Startup
    {
        public IHost BuildHost([IHostBuilder hostBuilder]) { return hostBuilder.Build(); }
    }
    

Method parameters wrapped in [...] above are optional.

How is Startup located?

Startup classes are looked up in the following order; the first match wins.

1. Startup declared on the test class

Apply [Startup(typeof(MyStartup))] on the test class.

2. Nested Startup

public class TestClass1
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services) { }
    }
}

3. Closest Startup in the namespace hierarchy

If the test class's full name is A.B.C.TestClass, Startup is looked up in this order:

  1. A.B.C.Startup
  2. A.B.Startup
  3. A.Startup
  4. Startup

4. Default Startup

A default Startup was required before 8.7.0, and is optional in some cases after 8.7.0. When it's required, add a startup class to your test project as shown above.

By default, Your.Test.Project.Startup, Your.Test.Project is used.

If you want to use a custom Startup, set XunitStartupAssembly and/or XunitStartupFullName in your project's PropertyGroup:

<Project>
  <PropertyGroup>
    <XunitStartupAssembly>Abc</XunitStartupAssembly>
    <XunitStartupFullName>Xyz</XunitStartupFullName>
  </PropertyGroup>
</Project>
XunitStartupAssembly XunitStartupFullName Resulting Startup
Your.Test.Project.Startup, Your.Test.Project
Abc Abc.Startup, Abc
Xyz Xyz, Your.Test.Project
Abc Xyz Xyz, Abc

Running tests in parallel

By default, xUnit runs all test cases within a test class synchronously. This package extends the test framework so tests can run in parallel.

If you register a custom ITestCollectionOrderer, test collections run in the order it specifies, which can be slower than running without one.

Enable it with the ParallelizationMode MSBuild property:

<Project>

  <PropertyGroup>
    <ParallelizationMode></ParallelizationMode>
  </PropertyGroup>

</Project>

This package supports two parallelization policies:

  1. Enhance (or true)

    Respects xUnit's own parallelization behavior.

  2. Force

    Ignores xUnit's parallelization behavior and forces tests to run in parallel.

A test class runs sequentially when it's decorated with [Collection] (unless ParallelizationMode is Force), [CollectionDefinition(DisableParallelization = true)], or [DisableParallelization]. A test method runs sequentially when it's decorated with [DisableParallelization] or [MemberData(DisableDiscoveryEnumeration = true)].

We recommend leaving parallelAlgorithm unset.

Thanks to Meziantou.Xunit.ParallelTestFramework for the inspiration.

Disabling Xunit.DependencyInjection

<Project>
    <PropertyGroup>
        <EnableXunitDependencyInjectionDefaultTestFrameworkAttribute>false</EnableXunitDependencyInjectionDefaultTestFrameworkAttribute>
    </PropertyGroup>
</Project>

Injecting ITestOutputHelper

Inject ITestOutputHelperAccessor instead of ITestOutputHelper directly, since the actual instance is only available while a test is running:

internal class DependencyClass : IDependency
{
    private readonly ITestOutputHelperAccessor _testOutputHelperAccessor;

    public DependencyClass(ITestOutputHelperAccessor testOutputHelperAccessor)
    {
        _testOutputHelperAccessor = testOutputHelperAccessor;
    }
}

Writing Microsoft.Extensions.Logging output to ITestOutputHelper

Install Xunit.DependencyInjection.Logging:

dotnet add package Xunit.DependencyInjection.Logging

The call chain must originate from the running test case; otherwise this feature won't work.

public class Startup
{
    public void ConfigureServices(IServiceCollection services) => services
        .AddLogging(lb => lb.AddXunitOutput());
}

Injecting IConfiguration or IHostEnvironment into Startup

public class Startup
{
    public void ConfigureHost(IHostBuilder hostBuilder) => hostBuilder
        .ConfigureServices((context, services) => { /* use context.Configuration / context.HostingEnvironment */ });
}

or

public class Startup
{
    public void ConfigureServices(IServiceCollection services, HostBuilderContext context)
    {
        // use context.Configuration / context.HostingEnvironment
    }
}

Customizing IConfiguration

public class Startup
{
    public void ConfigureHost(IHostBuilder hostBuilder) => hostBuilder
        .ConfigureHostConfiguration(builder => { })
        .ConfigureAppConfiguration((context, builder) => { });
}

How do I inject values with [MemberData]?

[MemberData] members are static and can't be resolved from the container, so use [MethodData] instead — it resolves the referenced method's parameters from DI.

Integrating with OpenTelemetry

Register the Xunit.DependencyInjection activity source with your TracerProviderBuilder to capture the spans this library emits:

TracerProviderBuilder builder;

builder.AddSource("Xunit.DependencyInjection");

Running code before and after each test

Inherit from BeforeAfterTest and register your implementation as a BeforeAfterTest service.

See the sample.

Initializing data on startup

For synchronous initialization, use the Configure method. For asynchronous initialization, use an IHostedService.

Package Description
Xunit.DependencyInjection.Logging Write Microsoft.Extensions.Logging output to ITestOutputHelper, see above
Xunit.DependencyInjection.AspNetCoreTesting Integration with ASP.NET Core Minimal API TestHost, see above
Xunit.DependencyInjection.StaFact Run [StaFact]/[StaTheory] test cases on an STA thread (e.g. for UI tests)
Xunit.DependencyInjection.xRetry Support xRetry's [RetryFact]/[RetryTheory]
Xunit.DependencyInjection.FsCheck Support FsCheck property-based [Property] tests
Xunit.DependencyInjection.Demystifier Use Ben.Demystifier to format exception stack traces
Xunit.DependencyInjection.Analyzer Roslyn analyzer that validates Startup class shape at compile time
Xunit.DependencyInjection.Template dotnet new xunit-di template to scaffold a new test project

StaFact

dotnet add package Xunit.DependencyInjection.StaFact
public class Startup
{
    public void ConfigureServices(IServiceCollection services) => services.AddStaFactSupport();
}
public class MyStaTests
{
    [StaFact]
    public void RunOnStaThread() { }

    [StaTheory]
    [InlineData(1)]
    public void RunOnStaThread(int value) { }
}

xRetry

dotnet add package Xunit.DependencyInjection.xRetry
public class Startup
{
    public void ConfigureServices(IServiceCollection services) => services.AddXRetrySupport();
}
public class MyRetryTests
{
    [RetryFact(3)]
    public void FlakyTest() { }
}

FsCheck

dotnet add package Xunit.DependencyInjection.FsCheck
public class Startup
{
    public void ConfigureServices(IServiceCollection services) => services.AddFsCheckSupport();
}

Demystifier

dotnet add package Xunit.DependencyInjection.Demystifier
public class Startup
{
    public void ConfigureServices(IServiceCollection services) => services.UseDemystifyExceptionFilter();
}

Analyzer

The analyzer is automatically added as an analyzer reference when you install Xunit.DependencyInjection, and reports compile-time diagnostics (e.g. multiple Startup constructors, invalid Configure* method signatures) so misconfigured Startup classes are caught early.

Project template

dotnet new install Xunit.DependencyInjection.Template
dotnet new create xunit-di -n MyTestProject

See Xunit.DependencyInjection.Template for details.

No packages depend on Xunit.DependencyInjection.

Use Microsoft.Extensions.DependencyInjection to inject xunit testclass. If you want write Microsoft.Extensions.Logging to ITestOutputHelper, please install Xunit.DependencyInjection.Logging.

Release notes:

11.3: Support FsCheck.Xunit.v3. 11.2: Update xunit.v3 to 3.2.2, Move HostManager.Start/Stop to AssemblyRunner. 11.1: Update xunit.v3 to 3.2.0. 11.0: C# 14, Downgrade Microsoft.Extensions.Hosting to 8.0. 10.8: Add CreateHostApplicationBuilder method. 10.7: Update xunit.v3 to 3.0.1, does not set ApplicationName if it is already configured. 10.6: Update xunit.v3 to 3.0.0. 10.5: Improve compatibility with top level statements. 10.4: Fix #146. 10.3: Update xunit.v3 to 2.0.0. 10.2: Fix some parallelization problem. 10.1: Allow the default startup to be missing anywhere. 10.0: Upgrade xunit to v3.

Version Downloads Last updated
12.0.1 15 08/25/2026
12.0.0 15 08/22/2026
11.3.2 13 08/22/2026
11.3.1 14 08/13/2026
11.3.0 21 06/14/2026
11.2.1 28 03/26/2026
11.2.0 25 03/26/2026
11.1.1 24 03/26/2026
11.1.0 29 03/26/2026
11.0.0 27 03/26/2026
10.8.0 23 03/26/2026
10.7.0 25 03/26/2026
10.6.0 25 03/26/2026
10.5.0 28 03/26/2026
10.4.2 25 03/26/2026
10.4.1 26 03/26/2026
10.4.0 26 03/26/2026
10.3.0 26 03/26/2026
10.2.1 26 03/26/2026
10.2.0 27 03/26/2026
10.1.1 21 03/26/2026
10.1.0 26 03/26/2026
10.0.0 31 03/26/2026
9.9.2 25 03/26/2026
9.9.1 25 03/26/2026
9.9.0 25 03/26/2026
9.8.0 27 03/26/2026
9.7.1 28 03/26/2026
9.7.0 25 03/26/2026
9.6.0 29 03/26/2026
9.5.0 25 03/26/2026
9.4.0 27 03/26/2026
9.3.1 26 03/26/2026
9.3.0 26 03/26/2026
9.2.1 25 03/26/2026
9.1.0 26 03/26/2026
9.0.1 23 03/26/2026
8.9.1 23 03/26/2026
8.9.0 22 03/26/2026
8.8.2 27 03/26/2026
8.8.1 28 03/26/2026
8.7.2 30 03/26/2026
8.7.1 27 03/26/2026
8.7.0 29 03/26/2026
8.6.1 22 03/26/2026
8.6.0 24 03/26/2026
8.5.0 27 03/25/2026
8.4.1 22 03/26/2026
8.4.0 27 03/26/2026
8.3.0 29 03/26/2026
8.2.0 25 03/26/2026
8.1.0 30 03/26/2026
8.0.0 28 03/26/2026
7.7.0 18 03/26/2026
7.6.0 25 03/26/2026
7.5.1 24 03/26/2026
7.4.0 26 03/26/2026
7.3.0 24 03/26/2026
7.2.0 26 03/26/2026
7.1.0 27 03/26/2026