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?
CodePudding user response:
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:
if (_mapper == null)
{
var mappingConfig = new MapperConfiguration(mc =>
{
mc.AddProfile(new SourceMappingProfile());
});
IMapper mapper = mappingConfig.CreateMapper();
_mapper = mapper;
}
They make sure there is an instance of the automapper that is properly initialized with the correct profile.
CodePudding user response:
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