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.