Thursday, 17 December 2015

Fluent Setups for AutoMapper

I've recently been using fluent interfaces quite a lot to make my test methods more readable. I'll go into a bit more detail in future posts, but here I just want to show you an example that I always use in my tests when I'm using AutoMapper.
[TestMethod]
public void Test_Method_With_Normal_Setup()
{
    var entity = new EntityOne();
    var viewModel = new ViewModelOne();
    var mockMappingEngine = new Mock<IMappingEngine>();
    mockMappingEngine.Setup(m => m.Map<EntityOne, ViewModelOne>(entity))
        .Returns(viewModel);

    var component = new BusinessComponent(mockMappingEngine.Object);

    // Some assertion here
}
The Setup line looks a bit messy to me. Adding a 'WithMapping' extension method on Mock<IMappingEngine> can help here.
public static Mock<IMappingEngine> WithMapping<TSource, TDestination>(
        this Mock<IMappingEngine> mockMapper, 
        TSource source, 
        TDestination expectedResult)
{
    mockMapper.Setup(m => m.Map<TSource, TDestination>(source))
        .Returns(expectedResult);

    return mockMapper;
}
The Setup line can now be simplified a bit:
[TestMethod]
public void Test_Method_With_Helper_Setup()
{
    var entity = new EntityOne();
    var viewModel = new ViewModelOne();
    var mockMappingEngine = new Mock<IMappingEngine>();
    mockMappingEngine.WithMapping(entity, viewModel);

    var component = new BusinessComponent(mockMappingEngine.Object);

    // Some assertion here
}
Because the WithMapping extension method returns a Mock<IMappingEngine> calls can be chained together, so if you've got multiple setups this approach can greatly improve the readability of the test method.

No comments:

Post a Comment