I have 2 classes to map:
public class Note
{
public Guid UserId { get; set; }
public Guid Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public DateTime CreationDate { get; set; }
public DateTime EditDate { get; set; }
}
public class NoteDetailsVm : IMapWith<Note>
{
public Guid Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public DateTime CreationDate { get; set; }
public DateTime EditDate { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<Note, NoteDetailsVm>();
}
}
Here is the mapping profile and the mapping interface:
public class AssemblyMappingProfile : Profile
{
public AssemblyMappingProfile(Assembly assembly) =>
ApplyMappingsFromAssembly(assembly);
private void ApplyMappingsFromAssembly(Assembly assembly)
{
var types = (from t in assembly.GetExportedTypes()
where t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapWith<>))
select t).ToList();
foreach (var type in types)
{
var instance = Activator.CreateInstance(type);
var methodInfo = type.GetMethod("Mapping");
methodInfo?.Invoke(instance, new object[] { this });
}
}
}
public interface IMapWith<T>
{
void Mapping(Profile profile) =>
profile.CreateMap(typeof(T), GetType());
}
I use this method to handle requests and get the viewmodel:
public async Task<NoteDetailsVm> Handle(GetNoteDetailsQuery request, CancellationToken cancellationToken)
{
var entity = await _dbContext.Notes.FirstOrDefaultAsync(note => note.Id == request.Id, cancellationToken);
if (entity == null || entity.UserId != request.UserId)
{
throw new NotFoundException(nameof(Note), request.Id);
}
return _mapper.Map<NoteDetailsVm>(entity);
}
So when I run the tests, I get such error though I have the necessary mappings:
AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.
AutoMapper.AutoMapperMappingException
Missing type map configuration or unsupported mapping.
Mapping types:
Note -> NoteDetailsVm
Notes.Domain.Note -> Notes.Application.Notes.Queries.GetNoteDetails.NoteDetailsVm
at lambda_method259(Closure , Object , NoteDetailsVm , ResolutionContext )
at Notes.Application.Notes.Queries.GetNoteDetails.GetNoteDetailsQueryHandler.Handle(GetNoteDetailsQuery request, CancellationToken cancellationToken)
Why isn’t the mapping working and how can I fix this?
2
Answers
Ok, I've managed to solve the problem, it had nothing to do with the code above. Just passed the wrong assembly to the profile constructor
You most probably don’t handle initialization in your tests. Check this guide here: https://www.thecodebuzz.com/unit-test-mock-automapper-asp-net-core-imapper/
The essence of it are these lines of code:
They make sure there is an instance of the automapper that is properly initialized with the correct profile.