Automapper unable to map foreign key properties in unit test project

Viewed 224

I have declared a map that maps an entity to a DTO. That DTO has a foreign key reference to another DTO that has to be mapped by automapper, using ProjectTo. This works perfectly fine when running the solution, but when i use the maps in my unit tests, in doesnt work until i remove the foreign key property from my DTO. I think there is something missing in my AutoMapper setup, but im not sure.

The model looks like this:

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; }
}

The map looks like this:

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 has it's own map that works perfectly fine on it's own. Above map is used like this:

return ReadContext.Reports
            .Where(x => x.Database == databaseType && x.ReportedDate == null)
            .ProjectTo<PendingReportDto>(_mapper.ConfigurationProvider)
            .ToListAsync(cancellationToken: cancellationToken);

When doing that i get the following error:

System.ArgumentNullException: Value cannot be null. (Parameter 'bindings')

Automapper is setup like this in unit test project:

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();
    }
}

It works if i use a select statement, instead of using ProjectTo to map to my DTO.

UPDATE:

Further investigation shows that the culprit might be me running an in-memory database, instead of my regular database, when running my unit tests. If i swap it out, even with the same dataset, it works as intended. Could this be a bug with EF Core in-memory db and automapper?

1 Answers

So im pretty sure I found the issue with using ProjectTo to map reverse navigation properties. The issue doesn't lie with Automapper itself or the way I have configurated it in my test setup.

The culprit seems to be the db provider: Entity Framework Core in-memory db.

If i swap out the database with a localdb or a regular MS SQL DB, it works just fine. The in-memory db provider has certain limitations, which seems to limit the usage of ProjectTo with Automapper.

Source: https://docs.microsoft.com/en-us/ef/core/testing/

How to setup local db:

private static void SetupLocalDb(DbContextOptionsBuilder builder)
{
    builder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=Testing;Trusted_Connection=True;");
}
Related