Mocking out AutoMapper with Dependency Injection

I’m a big fan of AutoMapper, an open-source object/object mapper for .NET. One thing I’ve noticed, however, is that all the examples I’ve seen all talk to the static Mapper class. This becomes a real pain when you need to test something that uses AutoMapper, because you can’t swap it out for testing purposes:

public class ReadingListService : IReadingListService
{
    IValidator<ReadingListForm> validator; // injected
    ReadingListRepository repository; // injected

    ...

    public ReadingList SaveReadingList(ReadingListForm form)
    {
        this.validator.ValidateAndThrow(form);

        // ugly global dependency :(
        ReadingList readingList = Mapper.Map<ReadingListForm, ReadingList>(form);
        
        this.repository.Save(readingList);
        return readingList;
    }

I don’t want to have to set up the Mapper when I’m testing ReadingListService’s interaction with the repository, validator, etc — especially because this particular mapping scenario uses custom resolvers which in have services injected into them as well (yawn).

Instead, I can break this dependency by replacing the Mapper reference with an instance of IMapperEngine, which has methods with the same signature as Mapper.Map:

public class ReadingListService : IReadingListService
{
    IValidator<ReadingListForm> validator; // injected
    ReadingListRepository repository; // injected
    IMappingEngine mapper; // injected!

    ...

    public ReadingList SaveReadingList(ReadingListForm form)
    {
        this.validator.ValidateAndThrow(form);

        // now mockable just like validator and repository :)
        ReadingList readingList = this.mapper.Map<ReadingListForm, ReadingList>(form);
        
        this.repository.Save(readingList);
        return readingList;
    }

I can now mock out AutoMapper, and use it A) to test that AutoMapper gets called in the appropriate scenarios B) to streamline other tests by just returning a known value etc.

The Mapper class holds a singleton to IMapperEngine in its Engine property, so you can register this with your IoC container etc.

May 7, 2009

4 Comments

Chris on May 8, 2009 at 7:02 am.

Cool. Think you might mean to type IMappingEngine mapper; // injected! above though.

Richard on May 8, 2009 at 8:14 am.

@Chris thanks, fixed :)

Fergal O'Donnell on September 20, 2010 at 11:51 pm.

You can take this one step further. Instead of using Automappers IMappingEngine interface write a facade (your own mapper interface). This interface would just call back to the Mapping Engine.

Doing this will allow you to swap objects mappers at a later stage.

Glenn Moseley on July 15, 2011 at 9:36 am.

Thanks for sharing. This helped alot.

Leave a Reply