Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/pengweiqhca/Xunit.DependencyInjection
Use Microsoft.Extensions.DependencyInjection to resolve xUnit test cases.
https://github.com/pengweiqhca/Xunit.DependencyInjection
ioc xunit
Last synced: 2 months ago
JSON representation
Use Microsoft.Extensions.DependencyInjection to resolve xUnit test cases.
- Host: GitHub
- URL: https://github.com/pengweiqhca/Xunit.DependencyInjection
- Owner: pengweiqhca
- License: mit
- Created: 2018-02-06T09:36:52.000Z (almost 7 years ago)
- Default Branch: main
- Last Pushed: 2024-10-30T14:19:50.000Z (3 months ago)
- Last Synced: 2024-11-08T06:48:48.251Z (2 months ago)
- Topics: ioc, xunit
- Language: C#
- Homepage:
- Size: 481 KB
- Stars: 370
- Watchers: 10
- Forks: 49
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# Use `Microsoft.Extensions.DependencyInjection` to resolve xUnit test cases
## How to use
Install the [Nuget](https://www.nuget.org/packages/Xunit.DependencyInjection) package.
```sh
dotnet add package Xunit.DependencyInjection
```In your testing project, add the following framework
```cs
namespace Your.Test.Project
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient();
}
}
}
```Example test `class`.
```cs
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 to `IHostedService`.
## Integration asp.net core TestHost(3.0+)
### Asp.Net Core Startup
```sh
dotnet add package Microsoft.AspNetCore.TestHost
``````C#
public class Startup
{
public void ConfigureHost(IHostBuilder hostBuilder) => hostBuilder
.ConfigureWebHost[Defaults](webHostBuilder => webHostBuilder
.UseTestServer(options => options.PreserveExecutionContext = true)
.UseStartup());
}
```### MinimalApi
If you use MinimalApi rather than asp.net core Startup class.
Add package reference for `Xunit.DependencyInjection.AspNetCoreTesting`
```sh
dotnet add package Xunit.DependencyInjection.AspNetCoreTesting
``````C#
public class Startup
{
public IHostBuilder CreateHostBuilder() => MinimalApiHostBuilderFactory.GetHostBuilder();
}
```> Maybe your asp.net core project should InternalsVisibleTo or add `public partial class Program {}` in the end of `Program.cs`;
>
> Detail see [Xunit.DependencyInjection.Test.AspNetCore](https://github.com/pengweiqhca/Xunit.DependencyInjection/tree/main/test/Xunit.DependencyInjection.Test.AspNetCore)## `Startup` limitation
* `CreateHostBuilder` method
```C#
public class Startup
{
public IHostBuilder CreateHostBuilder([AssemblyName assemblyName]) { }
}
```* `ConfigureHost` method
```C#
public class Startup
{
public void ConfigureHost(IHostBuilder hostBuilder) { }
}
```* `ConfigureServices` method
```C#
public class Startup
{
public void ConfigureServices(IServiceCollection services[, HostBuilderContext context]) { }
}
```* `Configure` method
Anything defined in `ConfigureServices`, can be specified in the `Configure` method signature. These services are injected if they're available.
## How to find `Startup`?
### 1. Specific startup
Declare [Startup] on test class
### 2. Nested startup
```C#
public class TestClass1
{
public class Startup
{
public void ConfigureServices(IServiceCollection services) { }
}
```### 3. Closest startup
If the class type full name is "A.B.C.TestClass", find Startup in the following order:
1. `A.B.C.Startup`
2. `A.B.Startup`
3. `A.Startup`
4. `Startup`### 4. Default 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
```xml
Abc
Xyz
```
| XunitStartupAssembly | XunitStartupFullName | Startup |
| -------------------- | -------------------- | -------------------------------------------- |
| | | Your.Test.Project.Startup, Your.Test.Project |
| Abc | | Abc.Startup, Abc |
| | Xyz | Xyz, Your.Test.Project |
| Abc | Xyz | Xyz, Abc |## Parallel
By default, xUnit runs all test cases in a test class synchronously. This package can extend the test framework to execute tests in parallel.
```xml
```
This package has two policies to run test cases in parallel.
1. Enhance or true
Respect xunit [parallelization](https://xunit.net/docs/running-tests-in-parallel) behavior.
2. ForceIgnore xunit [parallelization](https://xunit.net/docs/running-tests-in-parallel) behavior and force running tests in parallel.
If [`[Collection]`](https://github.com/xunit/xunit/issues/1227#issuecomment-297131879)(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`**
> Thanks [Meziantou.Xunit.ParallelTestFramework](https://github.com/meziantou/Meziantou.Xunit.ParallelTestFramework)
## How to disable Xunit.DependencyInjection
```xml
false
```
## How to inject ITestOutputHelper
```C#
internal class DependencyClass : IDependency
{
private readonly ITestOutputHelperAccessor _testOutputHelperAccessor;public DependencyClass(ITestOutputHelperAccessor testOutputHelperAccessor)
{
_testOutputHelperAccessor = testOutputHelperAccessor;
}
}
```## Write `Microsoft.Extensions.Logging` to `ITestOutputHelper`
Add package reference for `Xunit.DependencyInjection.Logging`
```sh
dotnet add package Xunit.DependencyInjection.Logging
```> The call chain must be from the test case. If not, this feature will not work.
```C#
public class Startup
{
public void ConfigureServices(IServiceCollection services) => services
.AddLogging(lb => lb.AddXunitOutput());
}
```## How to inject `IConfiguration` or `IHostEnvironment` into `Startup`?
```C#
public class Startup
{
public void ConfigureHost(IHostBuilder hostBuilder) => hostBuilder
.ConfigureServices((context, services) => { context.XXXX });
}
```or
```C#
public class Startup
{
public void ConfigureServices(IServiceCollection services, HostBuilderContext context)
{
context.XXXX;
}
}
```## How to configure `IConfiguration`?
```C#
public class Startup
{
public void ConfigureHost(IHostBuilder hostBuilder) => hostBuilder
.ConfigureHostConfiguration(builder => { })
.ConfigureAppConfiguration((context, builder) => { });
}
```## [MemberData] how to inject?
Use **[MethodData]**
## Integrate OpenTelemetry
```C#
TracerProviderBuilder builder;builder.AddSource("Xunit.DependencyInjection");
```## Do something before and after test case
Inherit `BeforeAfterTest` and register as `BeforeAfterTest` service.
[See demo](https://github.com/pengweiqhca/Xunit.DependencyInjection/blob/main/test/Xunit.DependencyInjection.Test/BeforeAfterTestTest.cs#13).
## Initialize some data on startup.
If it is synchronous initialization, you can use the `Configure` method. If it is asynchronous initialization, you should use `IHostedService`.