XUnit v2 users: please use v2 branch.
Xunit.DependencyInjection.SkippableFact are obsoleted on xunit.v3.
Install the NuGet package.
dotnet add package Xunit.DependencyInjectionIn your testing project, add the following framework
namespace Your.Test.Project
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IDependency, DependencyClass>();
}
}
}Example test 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.DependencyInjectionis built into the generic host and fully supports its lifecycle, allowing you to use all features supported by the generic host, including but not limited toIHostedService.
dotnet add package Microsoft.AspNetCore.TestHostpublic class Startup
{
public void ConfigureHost(IHostBuilder hostBuilder) => hostBuilder
.ConfigureWebHost[Defaults](webHostBuilder => webHostBuilder
.UseTestServer(options => options.PreserveExecutionContext = true)
.UseStartup<AspNetCoreStartup>());
}If you use MinimalApi rather than asp.net core Startup class.
Add package reference for Xunit.DependencyInjection.AspNetCoreTesting
dotnet add package Xunit.DependencyInjection.AspNetCoreTestingpublic class Startup
{
public IHostBuilder CreateHostBuilder() => MinimalApiHostBuilderFactory.GetHostBuilder<Program>();
}Maybe your asp.net core project should InternalsVisibleTo or add
public partial class Program {}in the end ofProgram.cs;Detail see Xunit.DependencyInjection.Test.AspNetCore
Startup supports two configuration styles, and the Configure method is supported by both.
-
CreateHostApplicationBuildermethodNOTE: If this method signature is not found, the host is built by simply calling
Host.CreateEmptyApplicationBuilder(new() { ApplicationName = assemblyName.Name });.public HostApplicationBuilder CreateHostApplicationBuilder([AssemblyName assemblyName]) { }
-
ConfigureHostApplicationBuildermethod (distinguish by this method)public void ConfigureHostApplicationBuilder(IHostApplicationBuilder hostApplicationBuilder) { }
-
BuildHostApplicationBuildermethodNOTE: If this method signature is not found, the host is built by simply calling
hostApplicationBuilder.Build();.public IHost BuildHostApplicationBuilder(HostApplicationBuilder hostApplicationBuilder) { return hostApplicationBuilder.Build(); }
-
CreateHostBuildermethodpublic class Startup { public IHostBuilder CreateHostBuilder([AssemblyName assemblyName]) { } }
-
ConfigureHostmethodpublic class Startup { public void ConfigureHost(IHostBuilder hostBuilder) { } }
-
ConfigureServicesmethodpublic class Startup { public void ConfigureServices(IServiceCollection services[, HostBuilderContext context]) { } }
-
BuildHostmethodNOTE: If this method signature is not found, the host is built by simply calling
hostBuilder.Build();.public class Startup { public IHost BuildHost([IHostBuilder hostBuilder]) { return hostBuilder.Build(); } }
Declare [Startup] on test class
public class TestClass1
{
public class Startup
{
public void ConfigureServices(IServiceCollection services) { }
}If the class type full name is "A.B.C.TestClass", find Startup in the following order:
A.B.C.StartupA.B.StartupA.StartupStartup
Default startup is required before 8.7.0, is optional in some case after 8.7.0.
If is required, please add a startup class in your test project.
Default is find Your.Test.Project.Startup, Your.Test.Project.
If you want to use a special Startup, you can define XunitStartupAssembly and XunitStartupFullName in the PropertyGroup section
<Project>
<PropertyGroup>
<XunitStartupAssembly>Abc</XunitStartupAssembly>
<XunitStartupFullName>Xyz</XunitStartupFullName>
</PropertyGroup>
</Project>| XunitStartupAssembly | XunitStartupFullName | Startup |
|---|---|---|
| Your.Test.Project.Startup, Your.Test.Project | ||
| Abc | Abc.Startup, Abc | |
| Xyz | Xyz, Your.Test.Project | |
| Abc | Xyz | Xyz, Abc |
By default, xUnit runs all test cases in a test class synchronously. This package can extend the test framework to execute tests in parallel.
If you register a custom
ITestCollectionOrderer, test collections will be run in the specified order, which may be slower than running without the customITestCollectionOrderer.
<Project>
<PropertyGroup>
<ParallelizationMode></ParallelizationMode>
</PropertyGroup>
</Project>This package has two policies to run test cases in parallel.
-
Enhance or true
Respect xunit parallelization behavior.
-
Force
Ignore xunit parallelization behavior and force running tests in parallel.
If [Collection](if ParallelizationMode is not Force), [CollectionDefinition(DisableParallelization = true)], [DisableParallelization] declared on the test class, the test class will run sequentially. If [DisableParallelization], [MemberData(DisableDiscoveryEnumeration = true)] declared on the test method, the test method will run sequentially.
It is recommended without setting parallelAlgorithm
<Project>
<PropertyGroup>
<EnableXunitDependencyInjectionDefaultTestFrameworkAttribute>false</EnableXunitDependencyInjectionDefaultTestFrameworkAttribute>
</PropertyGroup>
</Project>internal class DependencyClass : IDependency
{
private readonly ITestOutputHelperAccessor _testOutputHelperAccessor;
public DependencyClass(ITestOutputHelperAccessor testOutputHelperAccessor)
{
_testOutputHelperAccessor = testOutputHelperAccessor;
}
}Add package reference for Xunit.DependencyInjection.Logging
dotnet add package Xunit.DependencyInjection.LoggingThe call chain must be from the test case. If not, this feature will not work.
public class Startup
{
public void ConfigureServices(IServiceCollection services) => services
.AddLogging(lb => lb.AddXunitOutput());
}public class Startup
{
public void ConfigureHost(IHostBuilder hostBuilder) => hostBuilder
.ConfigureServices((context, services) => { context.XXXX });
}or
public class Startup
{
public void ConfigureServices(IServiceCollection services, HostBuilderContext context)
{
context.XXXX;
}
}public class Startup
{
public void ConfigureHost(IHostBuilder hostBuilder) => hostBuilder
.ConfigureHostConfiguration(builder => { })
.ConfigureAppConfiguration((context, builder) => { });
}Use [MethodData]
TracerProviderBuilder builder;
builder.AddSource("Xunit.DependencyInjection");Inherit BeforeAfterTest and register as BeforeAfterTest service.
If it is synchronous initialization, you can use the Configure method. If it is asynchronous initialization, you should use IHostedService.