与AutoMapper的集成测试无法初始化配置 [英] Integration Testing with AutoMapper fails to initialise 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
集成测试
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();
}
问题
调用控制器方法后,集成测试失败:
Problem
The integration test fails after the controller method is invoked:
var response = await _client.PostAsync("/api/controller", stringContent);
失败,因为尚未初始化AutoMapper.
我的理解是,由于TestServer
具有UseStartup
方法,因此它应该使用api Startup.cs
类中配置的所有服务(UseContentRoot
指向我的api项目根目录)
It fails because AutoMapper has not been initialised.
The way I understood this was that since the TestServer
has the UseStartup
method, it should use all the services configured in the api Startup.cs
class (the UseContentRoot
is pointing to my api project root)
这显然没有发生.有人可以告诉我如何配置TestServer
以便正确选择AutoMapper配置吗?
This clearly isn't happening. Could someone show me how I need to configure the TestServer
so that the AutoMapper configuration is picked up correctly please?
推荐答案
或仅使用此行
services.AddAutoMapper(typeof(Startup));
代替
var assembly = typeof(Program).GetTypeInfo().Assembly;
services.AddAutoMapper(assembly);
我认为这更清晰,更干净
which is more clear and clean in my opinion
这篇关于与AutoMapper的集成测试无法初始化配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!