2

initialise Cadres & paquetstests d'intégration avec AutoMapper ne parvient pas à la configuration

.NETCoreApp 1.1 
Xunit 2.2.0 
AutoMapper 6.0.2 
Microsoft.AspNetCore.TestHost 1.1.1 
Microsoft.NET.Test.Sdk 15.0.0 

Intégration test

public class ControllerRequestsShould 
{ 
    private readonly TestServer _server; 
    private readonly HttpClient _client; 

    public ControllerRequestsShould() 
    { 
     _server = new TestServer(new WebHostBuilder() 
      .UseContentRoot(Constants.apiProjectRoot) 
      .UseStartup<Startup>() 
      .UseEnvironment(Constants.testingEnvironment)); 
     _client = _server.CreateClient(); 
     _client.BaseAddress = new Uri(Constants.localHostUri); 
    } 

    [Fact] 
    public async Task CreateAnEntity() 
    { 
     // Arrange 
     var entityForCreationDto = new entityForCreationDto { Code = "00001", Name = "Entity One" }; 
     var jsonContent = JsonConvert.SerializeObject(entityForCreationDto); 
     var stringContent = new StringContent(jsonContent); 
     stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 

     // Act 
     var response = await _client.PostAsync("/api/controller", stringContent); 
     response.EnsureSuccessStatusCode(); 

     // Assert 
     Assert.Equal(HttpStatusCode.OK, response.StatusCode); 
    } 
} 

Startup.cs

public class Startup 
{ 
    public IConfigurationRoot Configuration { get; } 

    public Startup(IHostingEnvironment env) 
    { 
     var builder = new ConfigurationBuilder() 
      .SetBasePath(env.ContentRootPath) 
      .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 
      .AddEnvironmentVariables(); 
     Configuration = builder.Build(); 
    } 

    // This method gets called by the runtime. Use this method to add services to the container. 
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 
    public void ConfigureServices(IServiceCollection services) 
    { 
     // Add framework services 
     services.AddMvc(setupAction => 
     { 
      setupAction.ReturnHttpNotAcceptable = true; 
      setupAction.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter()); 
      setupAction.InputFormatters.Add(new XmlDataContractSerializerInputFormatter()); 
     }); 

     // Db context configuration 
     var connectionString = Configuration["ConnectionStrings:DefaultConnection"]; 
     services.AddDbContext<YourContext>(options => 
     { 
      options.UseSqlServer(connectionString); 
     }); 

     // Register services for dependency injection 
     services.AddScoped<IYourRepository, YourRepository>(); 

     services.AddSingleton<IActionContextAccessor, ActionContextAccessor>(); 

     services.AddScoped<IUrlHelper, UrlHelper>(implementationFactory => 
     { 
      var actionContext = 
       implementationFactory.GetService<IActionContextAccessor>().ActionContext; 
      return new UrlHelper(actionContext); 
     }); 
    } 

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
    { 
     loggerFactory.AddConsole(); 
     loggerFactory.AddDebug(LogLevel.Information); 
     loggerFactory.AddNLog(); 

     if (env.IsDevelopment()) 
     { 
      app.UseDeveloperExceptionPage(); 
     } 
     else 
     { 
      app.UseExceptionHandler(appBuilder => 
      { 
       appBuilder.Run(async context => 
       { 
        var exceptionHandlerFeature = context.Features.Get<IExceptionHandlerFeature>(); 
        if (exceptionHandlerFeature != null) 
        { 
         var logger = loggerFactory.CreateLogger("Global exception logger"); 
         logger.LogError(500, 
          exceptionHandlerFeature.Error, 
          exceptionHandlerFeature.Error.Message); 
        } 

        context.Response.StatusCode = 500; 
        await context.Response.WriteAsync("An unexpected fault happened. Try again later"); 
       }); 
      }); 
     } 

     Mapper.Initialize(cfg => 
     { 
      cfg.CreateMap<DataStore.Entities.Entity, Models.EntityDto>(); 
      cfg.CreateMap<Models.EntityDto, DataStore.Entities.Entity>(); 
      cfg.CreateMap<Models.EntityForCreationDto, DataStore.Entities.Entity>(); 
      cfg.CreateMap<DataStore.Entities.Entity, Models.EntityForCreationDto>(); 
     }); 

     app.UseMvc(); 
    } 

Problème
Le test d'intégration échoue après la méthode du contrôleur est invoquée:

var response = await _client.PostAsync("/api/controller", stringContent); 

Il échoue parce que AutoMapper n'a pas été initialisées. La façon dont je compris cela était que depuis le TestServer a la méthode UseStartup, il doit utiliser tous les services configurés dans l'api Startup.cs classe (la UseContentRoot pointe vers mon projet api racine)

Ceci est clairement pas le cas. Quelqu'un pourrait-il me montrer comment j'ai besoin de configurer le TestServer de sorte que la configuration AutoMapper est ramassé correctement s'il vous plaît?

+0

Afficher la classe de démarrage – Nkosi

+0

Avez-vous trouvé une solution à ce problème? – bigyanshr

Répondre

1

Vous devez spécifier l'ensemble dans la méthode ConfigureServices: var assembly = typeof(Program).GetTypeInfo().Assembly; services.AddAutoMapper(assembly); J'utilise des modules Automapper, de sorte que la configuration de mappage est automatiquement capté par AutoMapper, mais même alors, vous avez encore besoin de configuration ci-dessus.

1

Ou tout simplement utiliser cette ligne

services.AddAutoMapper(typeof(Startup)); 

au lieu de

var assembly = typeof(Program).GetTypeInfo().Assembly; 
services.AddAutoMapper(assembly); 

qui est plus claire et propre à mon avis