Estoy tratando de implementar la inyección de dependencia en la prueba Xunit para AppService. El objetivo ideal es ejecutar el programa de aplicación original Inicio/configuración y usar cualquier inyección de dependencia que haya en el Inicio, en lugar de reiniciar todo el DI nuevamente en mi prueba, ese es todo el objetivo en cuestión.
Actualización: la respuesta de Mohsen está cerca. Necesita actualizar un par de errores de sintaxis/requisitos para que funcione.
Por alguna razón, la aplicación original funciona y puede llamar al Servicio de aplicaciones del Departamento. Sin embargo, no puede llamar a Xunit. Finalmente conseguí que Testserver funcionara usando el Inicio y la Configuración desde la aplicación original. Ahora recibiendo el error a continuación:
Message: The following constructor parameters did not have matching fixture data: IDepartmentAppService departmentAppService namespace Testing.IntegrationTests { public class DepartmentAppServiceTest { public DBContext context; public IDepartmentAppService departmentAppService; public DepartmentAppServiceTest(IDepartmentAppService departmentAppService) { this.departmentAppService = departmentAppService; } [Fact] public async Task Get_DepartmentById_Are_Equal() { var options = new DbContextOptionsBuilder<SharedServicesContext>() .UseInMemoryDatabase(databaseName: "TestDatabase") .Options; context = new DBContext(options); TestServer _server = new TestServer(new WebHostBuilder() .UseContentRoot("C:\\OriginalApplication") .UseEnvironment("Development") .UseConfiguration(new ConfigurationBuilder() .SetBasePath("C:\\OriginalApplication") .AddJsonFile("appsettings.json") .Build()).UseStartup<Startup>()); context.Department.Add(new Department { DepartmentId = 2, DepartmentCode = "123", DepartmentName = "ABC" }); context.SaveChanges(); var departmentDto = await departmentAppService.GetDepartmentById(2); Assert.Equal("123", departmentDto.DepartmentCode); } } }Estoy recibiendo este error:
Message: The following constructor parameters did not have matching fixture data: IDepartmentAppService departmentAppServiceNecesita usar la inyección de dependencia en las pruebas como una aplicación real. La aplicación original hace esto. Las respuestas a continuación no son suficientes actualmente, una usa la burla que no es el objetivo actual, otra respuesta usa el Controlador que elude el propósito de la pregunta.
Nota: IDepartmentAppService depende de IDepartmentRepository, que también se inyecta en la clase de inicio y las dependencias de Automapper. Es por eso que llama a toda la clase de inicio.
Buenos recursos:
Use Custom Web Application Factory y ServiceProvider.GetRequiredService a continuación, siéntase libre de editar y optimizar la respuesta
Fábrica de aplicaciones web personalizadas:
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); }); }); } }Examen de integración:
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); } } }Recursos:
https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2
https://fullstackmark.com/post/20/indoloro-integración-pruebas-con-aspnet-core-web-api
Cuando estás probando. Debe usar bibliotecas de simulación o inyectar su servicio directamente en el constructor, es decir.
public DBContext context; public IDepartmentAppService departmentAppService; /// Inject DepartmentAppService here public DepartmentAppServiceTest(DepartmentAppService departmentAppService) { this.departmentAppService = departmentAppService; }