How to unit test AutoMapper profile with AfterMap using IMappingAction

Viewed 1114

How can i unit test a profile that uses AfterMap with IMappingAction that has an injected service.

MappingProfile.cs

public MappingProfile()
{
    CreateMap<string, string>()
        .ConvertUsing<Core.Converter.TrimStringValueConverter>();   
    CreateMap<TestModel, TestEntity>(
        .AfterMap<AfterMapAction>();
}

AfterMapAction.cs

public class AfterMapAction: IMappingAction<TestModel, TestEntity>
{
    private readonly IAfterMapService _afterMapService ;
    public AfterMapAction(IAfterMapService aftermapService)
    {
        _afterMapService  = afterMapService  ?? throw new ArgumentNullException(nameof(afterMapService));
    }

    public void Process(TestModel, TestEntity destination, ResolutionContext context)
    {
        var somevalue = _afterMapService.DoAction(source);
        ...
    }
}

Test.cs

[TestMethod]
public void AutoMapperTest()
{
    // Arrange
    var model = new TestModel { Id = "4711" , Name = "Test" };
    var mapper = new Mapper(new MapperConfiguration(cfg =>
    {
        cfg.AddProfile<MappingProfile>();
    }));

    // Act
    var mappedObject = mapper.Map<Entity>(model);

    ...
}

When i run this test, i get following exception:

System.MissingMethodException: 'No parameterless constructor defined for type 'AfterMapAction'.

The usage of cfg.ConstructServicesUsing did not work. It always ends with an InvalidCastException.

How can i arrange the unit test, so AutoMapper can instantiate AfterMapAction?

1 Answers

I could solve this by using the IServiceCollection within the Unit Test.

// Arrange
var services = new ServiceCollection();
services.AddSingleton<AfterMapAction>();
services.AddSingleton<IAfterMapService, AfterMapService>();
services.AddAutoMapper(cfg => cfg.AddProfile<MappingProfile>());

var serviceProvider = services.BuildServiceProvider();
var mapper = serviceProvider.GetService<IMapper>();

// Act

Related