Automapper的ProjectTo与EFCore内存数据库(单元测试)不兼容

5
我们正在使用Automappers ProjectTo方法构建DTO对象,该对象是较大数据库视图的子集。在实际应用程序运行时,它能够按预期工作,但在使用EF Core内存数据库进行单元测试时,我们遇到了问题。无论查询什么内容,它似乎都只返回0个结果。以下是我尝试运行的测试代码。
[Fact]
public async Task GetTemplateAdHocReportList_ReturnsOnlyTemplateReports()
{
    await TestHelper.SeedFull(ReportContext); // Calls SeedAdHocReports below along with other seed methods

    var results = await _sut.GetTemplateAdHocReports();

    results.Where(x => !x.IsTemplate).Count().Should().Be(0);
}

这是种子数据:
public static async Task SeedAdHocReports(ReportContext context)
{
    var reports = new AdHocReport[]
    {
        new AdHocReport()
        {
            Id = 1,
                Name = "DevExtreme Example Report",
                IsTemplate = true,
                AdHocDataSourceId = 1,
                Fields = "[{\"caption\":\"Category\",\"dataField\":\"ProductCategoryName\",\"expanded\":true,\"area\":\"row\"},{\"caption\":\"Subcategory\",\"dataField\":\"ProductSubcategoryName\",\"area\":\"row\"},{\"caption\":\"Product\",\"dataField\":\"ProductName\",\"area\":\"row\"},{\"caption\":\"Date\",\"dataField\":\"DateKey\",\"dataType\":\"date\",\"area\":\"column\"},{\"caption\":\"Amount\",\"dataField\":\"SalesAmount\",\"summaryType\":\"sum\",\"format\":{\"type\":\"currency\",\"precision\":2,\"currency\":\"USD\"},\"area\":\"data\"},{\"caption\":\"Store\",\"dataField\":\"StoreName\"},{\"caption\":\"Quantity\",\"dataField\":\"SalesQuantity\",\"summaryType\":\"sum\"},{\"caption\":\"Unit Price\",\"dataField\":\"UnitPrice\",\"format\":\"currency\",\"summaryType\":\"sum\"},{\"dataField\":\"Id\",\"visible\":false}]",
                Status = true
        }
    };

    context.AdHocReports.AddRange(reports);
    await context.SaveChangesAsync();
}

这里是正在测试的GetTemplateAdHocReports方法

public async Task<IList<AdHocReportDto>> GetTemplateAdHocReports()
{
    //This gives the expected 1 object in the unit tests:
    var test = await _reportContext.AdHocReports.Where(x => x.Status && x.IsTemplate).OrderBy(x => x.Name).ToListAsync();

    //This always comes back with a count of 0 even though the seed data should return 1 result
    var results = await _reportContext.AdHocReports.Where(x => x.Status && x.IsTemplate).OrderBy(x => x.Name).ProjectTo<AdHocReportDto>(_mapper.ConfigurationProvider).ToListAsync();
    return results;
}

最后,如果这些对你有用,在这里提供构造函数:

public AdHocServiceTests()
{
    TestHelper = new TestHelper();

    var reportOptions = TestHelper.GetMockedReportDbOptions();
    ReportContext = new ReportContext(reportOptions);

    _sut = new AdHocService(ReportContext, TestHelper.Mapper, TestHelper.GetMockedNiceService().Object);
}

public TestHelper()
{
    var mappingConfig = new MapperConfiguration(cfg =>
    {
        cfg.AddProfile<ReportDtoMapperProfile>();
    });
    Mapper = mappingConfig.CreateMapper(); // public property on TestHelper
}

public AdHocService(ReportContext reportContext, IMapper mapper, INiceService niceService)
{
    _niceService = niceService;
    _mapper = mapper;
    _reportContext = reportContext;
}

那么最后的问题是为什么上面的 "var test =" 行起作用,但带有 ProjectTo 的下面的 "var results =" 行始终返回 0 个结果?

在VSCode中有没有一个插件可以做到这一点? - Nathan Kamenar
我从你发布的链接中获取了表达式的调试视图字符串。我无法使用插件使其更易读,但是看起来它的配置符合我的预期,并且像我所说的那样,在生产环境中它按预期工作,只有单元测试不起作用。这是生成的表达式:http://scratchpad.io/StackOverflow-Automapper-Issue - Nathan Kamenar
1
因为当我调试单元测试时,没有预期的投影,"var test"返回一个包含1个结果的列表,这是我所期望的,但是带有投影的"var results"却不是。每次它都返回一个空列表。 - Nathan Kamenar
我也遇到了这个问题。你解决了吗? - vahid tajari
2023年有任何更新吗? - Edgaras
显示剩余4条评论
1个回答

0

我也遇到了这个问题。

你的问题很可能出在 ReportDtoMapperProfile 类中(你没有向我们展示)。 我猜想你的自动映射配置文件将表链接到了一个子表,用于该属性:AdHocDataSourceId = 1

因为你忘记了填充 AdHockDataSource 表,所以自动映射器没有返回任何映射结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接