J'ai une classe de test avec un constructeur qui a besoin d'un IService.
public class ConsumerTests
{
private readonly IService _service;
public ConsumerTests(IService servie)
{
_service = service;
}
[Fact]
public void Should_()
{
//use _service
}
}
Je veux plugin mon conteneur DI de choix pour construire classe de test.
Est-ce possible avec xUnit?
Oui il y en a maintenant, ces deux questions et réponses devraient être consolidées à mon avis, voir réponse ici
Utilisez Factory Web Application Factory et ServiceProvider.GetRequiredService ci-dessous, n'hésitez pas à modifier et optimiser la réponse
CustomWebApplicationFactory:
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureAppConfiguration((hostingContext, configurationBuilder) =>
{
var type = typeof(TStartup);
var path = @"C:\\OriginalApplication";
configurationBuilder.AddJsonFile($"{path}\\appsettings.json", optional: true, reloadOnChange: true);
configurationBuilder.AddEnvironmentVariables();
});
// if you want to override Physical database with in-memory database
builder.ConfigureServices(services =>
{
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
services.AddDbContext<ApplicationDBContext>(options =>
{
options.UseInMemoryDatabase("DBInMemoryTest");
options.UseInternalServiceProvider(serviceProvider);
});
});
}
}
Test d'intégration:
public class DepartmentAppServiceTest : IClassFixture<CustomWebApplicationFactory<OriginalApplication.Startup>>
{
public CustomWebApplicationFactory<OriginalApplication.Startup> _factory;
public DepartmentAppServiceTest(CustomWebApplicationFactory<OriginalApplication.Startup> factory)
{
_factory = factory;
_factory.CreateClient();
}
[Fact]
public async Task ValidateDepartmentAppService()
{
using (var scope = _factory.Server.Host.Services.CreateScope())
{
var departmentAppService = scope.ServiceProvider.GetRequiredService<IDepartmentAppService>();
var dbtest = scope.ServiceProvider.GetRequiredService<ApplicationDBContext>();
dbtest.Department.Add(new Department { DepartmentId = 2, DepartmentCode = "123", DepartmentName = "ABC" });
dbtest.SaveChanges();
var departmentDto = await departmentAppService.GetDepartmentById(2);
Assert.Equal("123", departmentDto.DepartmentCode);
}
}
}
Ressources:
https://docs.Microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2
https://fullstackmark.com/post/20/pireless-integration-testing-with-aspnet-core-web-api
Il existe un moyen de le faire en utilisant le package nuget à partir de ce code source: https://github.com/dennisroche/xunit.ioc.autofac
Cela fonctionne très bien tant que vous utilisez [Fact]
, mais j'ai été bloqué lorsque j'ai commencé à utiliser [Theory]
. Il y a une demande d'extraction pour trier cela.
Pour me débloquer, j'ai utilisé CollectionFixture pour injecter Container et à partir du conteneur, je résous l'interface.