.NET Core 3.1中具有AutoMapper,WebApplicationFactory,Entity Framework和DTO的集成测试

问题描述

我们有一个API,其中包含大约十二种集成测试。所有测试都通过了,直到我添加了一些DTO并使用了AutoMapper。现在,所有测试使用AutoMapper和DTO的方法的测试都失败了。我提供了理解其中一项失败测试所需的所有代码。另外,我阅读了很多有关AutoMapper和以下StackOverflow帖子的信息:

  1. Integration Testing with AutoMapper fails to initialise configuration
  2. A kind of integration testing in ASP.NET Core,with EF and AutoMapper

Startup.cs

这是我们的Startup.ConfigureServices()。我已经尝试过注释掉和/或标记为“已尝试”的每个代码块。

 public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddDbContext<OurContext>(options =>
                options.UseSqlServer(Configuration["ConnectionString"]))
            .AddDbContext<OurContext>()
            .AddRazorPages()
            .AddMvcOptions(options => options.EnableEndpointRouting = false)
            .AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
        services
            .AddControllersWithViews();

        //ATTEMPTED
        //services
        //    .AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

        //ATTEMPTED
        //MapperConfiguration mapperConfiguration = new MapperConfiguration(mc =>
        //{
        //    mc.AddProfile(new OurProfile());
        //});
        //IMapper mapper = mapperConfiguration.CreateMapper();
        //services
        //    .AddSingleton(mapper);

        //ATTEMPTED
        //services
        //    .AddAutoMapper(typeof(Startup));

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

        //ATTEMPTED
        var assembly = typeof(Program).GetTypeInfo().Assembly;
        services.AddAutoMapper(cfg =>
        {
            cfg.AllowNullDestinationValues = true;
            cfg.CreateMap<OurModel,OurDto>()
                .IgnoreAllPropertiesWithAnInaccessibleSetter();
        },assembly);
    }

控制器

这是我们的控制者。

[Route("api/[controller]")]
[ApiController]
public class OurController : ControllerBase
{
    private readonly OurContext _context;

    protected readonly ILogger<OurController> Logger;

    private readonly IMapper _mapper;

    public OurController(OurContext context,ILogger<OurController> logger,IMapper mapper)
    {
        _context = context ??
            throw new ArgumentNullException(nameof(context));
        Logger = logger ??
                 throw new ArgumentNullException(nameof(logger));
        _mapper = mapper ??
                  throw new ArgumentNullException(nameof(mapper));
    }

    [HttpGet]
    public async Task<ActionResult<IEnumerable<OurDto>>> GetAll()
    {

        IQueryable<OurModel> models = _context.OurModel;

        IQueryable<OurDto> dtos = 
            _mapper.Map<IQueryable<OurDto>>(models);

        return await dtos.ToListAsync();
    }
}

配置文件,模型和DTO

个人资料

public class OurProfile : Profile
{
    public OurProfile()
    {
        CreateMap<OurModel,OurDto>();
    }
}

型号

public partial class OurModel
{
    public string Number { get; set; }
    public string Name1 { get; set; }
    public string Name2 { get; set; }
    public string Status { get; set; }
    public DateTime? Date { get; set; }
    public string Description { get; set; }
    public string Comment { get; set; }
    public string District { get; set; }
}

DTO

public class OurDto
{
    public string Number { get; set; }
    public string Name1 { get; set; }
    public string Name2 { get; set; }
    public string Status { get; set; }
    public DateTime? Date { get; set; }
    public string Description { get; set; }
    public string Comment { get; set; }
    public string District { get; set; }
}

测试装置

这是我们的测试装置。

public abstract class ApiClientFixture : IClassFixture<WebApplicationFactory<Startup>>
{
    private readonly WebApplicationFactory<Startup> _factory;

    protected abstract string RelativeUrl { get; }

    protected ApiClientFixture(WebApplicationFactory<Startup> factory)
    {
        _factory = factory;
    }

    protected HttpClient CreateClient()
    {
        HttpClient client;
        var builder = new UriBuilder();

        client = _factory.CreateClient();
        builder.Host = client.BaseAddress.Host;
        builder.Path = $"{RelativeUrl}";

        client.BaseAddress = builder.Uri;
        return client;
    }
}

测试

这是我们的测试班。该测试类中的单个测试失败。

public class Tests : ApiClientFixture
{
    public Tests(WebApplicationFactory<Startup> factory) : base(factory)
    {
    }

    protected override string RelativeUrl => "api/OurController/";

    [Fact]
    public async void GetAllReturnsSomething()
    {
        var response = await CreateClient().GetAsync("");

        Assert.True(response.IsSuccessStatusCode);
    }
}

调试测试时,我发现从提供给内存API的URL返回了500状态代码。

有人有建议吗?目前,我们有超过一半的测试失败了,我怀疑没有正确配置AutoMapper进行集成测试。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)