Automapper 无法在单元测试项目中映射外键属性
Posted
技术标签:
【中文标题】Automapper 无法在单元测试项目中映射外键属性【英文标题】:Automapper unable to map foreign key properties in unit test project 【发布时间】:2022-01-06 08:22:05 【问题描述】:我已经声明了一个将实体映射到 DTO 的映射。该 DTO 具有对另一个 DTO 的外键引用,该 DTO 必须由 automapper 使用 ProjectTo 进行映射。这在运行解决方案时工作得非常好,但是当我在单元测试中使用地图时,直到我从 DTO 中删除外键属性后才会工作。我认为我的 AutoMapper 设置中缺少某些内容,但我不确定。
模型如下所示:
public class PendingReportDto
public Guid Id get; set;
public Guid PatientId get; set;
public long Identifier get; set;
public DatabaseType Database get; set;
public DateTime? ReportedDate get; set;
public PatientDto Patient get; set;
public IdentifierType IdentifierType get; set;
地图是这样的:
CreateMap<Report, PendingReportDto>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
.ForMember(dest => dest.Database, opt => opt.MapFrom(src => src.Database))
.ForMember(dest => dest.PatientId, opt => opt.MapFrom(src => src.PatientId))
.ForMember(dest => dest.ReportedDate, opt => opt.MapFrom(src => src.ReportedDate))
.ForMember(dest => dest.Identifier, opt => opt.MapFrom(src => src.Identifier))
.ForMember(dest => dest.IdentifierType, opt => opt.MapFrom(src => src.IdentifierType))
.ForMember(dest => dest.Patient, opt => opt.MapFrom(src => src.Patient));
Patient 有自己的地图,可以自己完美运行。 上面的地图是这样使用的:
return ReadContext.Reports
.Where(x => x.Database == databaseType && x.ReportedDate == null)
.ProjectTo<PendingReportDto>(_mapper.ConfigurationProvider)
.ToListAsync(cancellationToken: cancellationToken);
执行此操作时,我收到以下错误:
System.ArgumentNullException: Value cannot be null. (Parameter 'bindings')
Automapper 在单元测试项目中是这样设置的:
public static class SetupAutomapper
public static IMapper Setup()
var config = new MapperConfiguration(opts =>
var profiles = typeof(MappingProfile).Assembly.GetTypes().Where(x => typeof(MappingProfile).IsAssignableFrom(x));
foreach (var profile in profiles.Distinct())
opts.AddProfile(Activator.CreateInstance(profile) as MappingProfile);
);
return config.CreateMapper();
如果我使用 select 语句而不是使用 ProjectTo 映射到我的 DTO,它会起作用。
更新:
进一步调查表明,罪魁祸首可能是我在运行单元测试时运行的是内存数据库,而不是我的常规数据库。如果我将其换掉,即使使用相同的数据集,它也会按预期工作。这可能是 EF Core 内存数据库和自动映射器的错误吗?
【问题讨论】:
进一步调查表明,罪魁祸首可能是我在运行单元测试时运行的是内存数据库,而不是我的常规数据库。如果我将其换掉,即使使用相同的数据集,它也会按预期工作。这可能是 EF Core 内存数据库和自动映射器的错误吗? 此外,配置文件似乎有效,正如我在上面的评论中所述。如果我将数据库从内存数据库更改为常规数据库,那么它工作得很好。此外,当我使用内存数据库时,除了通过反向导航属性进行映射之外,一切正常。 我看到您链接到程序集扫描以添加配置,但这肯定不是唯一的方法,因为 AutoMapper API 有一种方法可以一次添加一个配置文件。在另一个项目中,我只是添加了一个类型,它可以通过几种不同的方式完成 @LucianBargaoanu 我尝试通过添加配置文件。装配扫描,但它没有任何区别。我认为这可能是 Automapper 与 In-memory ef core 结合使用的东西 提供者所做的与 AM 无关。如果它适用于真实的数据库,您只需要使您的测试基础设施更接近真实的东西。我相信很多人已经这样做了。 【参考方案1】:所以我很确定我发现了使用 ProjectTo 映射反向导航属性的问题。问题不在于 Automapper 本身或我在测试设置中配置它的方式。
罪魁祸首似乎是数据库提供者:Entity Framework Core in-memory db。
如果我用 localdb 或常规 MS SQL DB 替换数据库,它就可以正常工作。 in-memory db provider 有一定的限制,这似乎限制了 ProjectTo 与 Automapper 的使用。
来源:https://docs.microsoft.com/en-us/ef/core/testing/
如何设置本地数据库:
private static void SetupLocalDb(DbContextOptionsBuilder builder)
builder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=Testing;Trusted_Connection=True;");
【讨论】:
以上是关于Automapper 无法在单元测试项目中映射外键属性的主要内容,如果未能解决你的问题,请参考以下文章