Mocking out AutoMapper with Dependency Injection

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.