Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoMapperMappingException - Missing type map configuration or unsupported mapping

Tags:

c#

automapper

When I implemented IReadOnlyList in my code, my unit test threw an AutoMapperMappingException.

From digging through articles and documentation, my guess is that AutoMapper needs special coding for readonly types. What would this look like?

Note: I tried Mapper.AssertConfigurationIsValid(); as another post suggested, but no improvements.

Test Name: CreateOrder_ValidContract_CreatesNewOrder Test FullName: ACME.Maintenance.Domain.Test.OrderServiceTest.CreateOrder_ValidContract_CreatesNewOrder Test Source: C:\Users\me\documents\visual studio 2015\Projects\ACME.Maintenance\ACME.Maintenance.Domain.Test\OrderServiceTest.cs : line 65 Test Outcome: Failed Test Duration: 0:00:00.0233941

Result StackTrace: at lambda_method(Closure , ContractDto , Contract , ResolutionContext ) at ACME.Maintenance.Domain.ContractService.GetById(String contractId) in C:\Users\me\documents\visual studio 2015\Projects\ACME.Maintenance\ACME.Maintenance.Domain\ContractService.cs:line 34 at ACME.Maintenance.Domain.Test.OrderServiceTest.CreateOrder_ValidContract_CreatesNewOrder() in C:\Users\me\documents\visual studio 2015\Projects\ACME.Maintenance\ACME.Maintenance.Domain.Test\OrderServiceTest.cs:line 69 Result Message: Test method ACME.Maintenance.Domain.Test.OrderServiceTest.CreateOrder_ValidContract_CreatesNewOrder threw exception: AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.

Mapping types: ContractDto -> Contract

ACME.Maintenance.Domain.DTO.ContractDto -> ACME.Maintenance.Domain.Contract

Mapper.Initialize(cfg => cfg.CreateMap<ContractDto, Contract>());
Mapper.Initialize(cfg => cfg.CreateMap<PartDto, Part>());
[TestMethod]
public void CreateOrder_ValidContract_CreatesNewOrder()
    {
        //Arrange
        var orderService = new OrderService();
        var contractService = new ContractService(_contractRepository);
        var contract = contractService.GetById(ValidContractId);

        // Act
        var newOrder = orderService.CreateOrder(contract);

        // Assert
        Assert.IsInstanceOfType(newOrder, typeof(Order));

        Guid guidOut;
        Assert.IsTrue(Guid.TryParse(newOrder.OrderId, out guidOut));

        Assert.AreEqual(newOrder.Status, ContractStatus.New);
        Assert.IsInstanceOfType(newOrder.Items, typeof(IReadOnlyList<OrderItem>));

    }

ContractService class:

public Contract GetById(string contractId)
    {
        var contractDto = _contractRepository.GetById(contractId);
        var contract = Mapper.Map<ContractDto, Contract>(contractDto);
        Mapper.AssertConfigurationIsValid();
        return contract;
    }

Contract class:

public class Contract
{
    public string ContractId { get; set; }
    public DateTime ExpirationDate { get; set; }

}

ContractDto class:

public class ContractDto
{
    public string ContractId { get; set; }
    public DateTime ExpirationDate { get; set; }

}
like image 220
Spencer H Avatar asked Jul 22 '16 18:07

Spencer H


1 Answers

Your problem is that you are calling Mapping.Initialize multiple times: it is not additive, so you are overwriting the previous mappings, and that's why you are losing the map from ContractDto to Contract

So in the Setup method of your test, you should call it like this:

Mapper.Initialize(cfg => {
     cfg.CreateMap<ContractDto, Contract>();
     cfg.CreateMap<PartDto, Part>();
});
like image 145
stuartd Avatar answered Sep 21 '22 18:09

stuartd