web-dev-qa-db-fra.com

Est-il possible d'utiliser l'injection de dépendances avec xUnit?

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?

20
Rookian

Oui il y en a maintenant, ces deux questions et réponses devraient être consolidées à mon avis, voir réponse ici

Net Core: exécuter toutes les injections de dépendances dans le test Xunit pour AppService, Repository, etc.

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

3
user11860043

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.

2
Siva Kandaraj