Install the Nuget package.
dotnet add package Xunit.DependencyInjection
In 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.DependencyInjection
is 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.TestHost
public 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.AspNetCoreTesting
public 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
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]) { }
}
-
Configure
methodAnything defined in
ConfigureServices
, can be specified in theConfigure
method signature. These services are injected if they're available.
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.Startup
A.B.Startup
A.Startup
Startup
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.
<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 to use xunit 2.8.0+ and 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.Logging
The 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
.