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.

Thursday, 10 December 2015

Unit Testing Legacy Code - Examples

Last time I wrote about the difficulties I've encountered unit testing legacy code. Today I'm going to show you a simple example that I used in a presentation at work a while ago. I've changed some of the class names but the general gist is the same.

I used a very simple MVC controller, with just a single action. I chose this controller on purpose due to its simplicity as it allowed me to communicate the core ideas very easily. I'll write about a more complex case at some point in the future.

I started with the following code:
public class ReferralController : BaseController
{
 public ActionResult Referral()
 {
  var viewModel = new ReferralViewModel();
  var entity = StaticEntityProvider.Get();

  viewModel.Reasons = entity.Reasons;

  return View(viewModel);
 }
}
Briefly this action creates a view model, gets an entity using a static method, sets a property on the view model using the retrieved entity, and finally returns the view with the view model.

One immediate problem stopping us from unit testing this method is the use of the static Get() method. A second problem that isn't apparent from this code is in the instantiation of the view model. I am of the firm opinion that view models should contain no behaviour or dependencies whatsoever. They should just contain simple properties with getters and setters. This is because their job is to hold data that can be bound to a UI (in this case an MVC view). That is their responsibility. Anything in addition to that violates the single responsibility principle. However in this application view models routinely contained logic, and for this initial refactoring I wasn't prepared to tackle that just yet.

So my refactoring focused on encapsulating the creation of the view model, and on eliminating the static method call. For the view model creation I created a factory interface as shown below:
public interface IViewModelFactory
{
 TModel Create<TModel>() where TModel : BaseViewModel, new();
}
I used a couple generic constraints because the view models all inherited from a base class and they all had a parameterless constructor. The interface has a very simple implementation:
public class ViewModelFactory : IViewModelFactory
{
 public TModel Create<TModel>() where TModel : BaseViewModel, new()
 {
  return new TModel();
 }
}
I then created a wrapper interface and class for the entity provider:
public interface IEntityProviderWrapper
{
 Entity Get();
}

public class EntityProviderWrapper : IEntityProviderWrapper
{
 public Entity Get()
 {
  return StaticEntityProvider.Get();
 }
}
Finally these interfaces can be injected into the controller as follows:
public class ReferralController : BaseController
{
 private readonly IViewModelFactory _viewModelFactory;
 private readonly IEntityProviderWrapper _entityProvider;

 public QuoteReferralController(IViewModelFactory viewModelFactory, IEntityProviderWrapper entityProvider)
 {
  _viewModelFactory = viewModelFactory;
  _entityProvider = entityProvider;
 }

 public ActionResult QuoteReferral()
 {
  var viewModel = _viewModelFactory.Create<ReferralViewModel>();
  var entity = _entityProvider.Get();

  viewModel.Reasons = entity.Reasons;

  return View(viewModel);
 }
}
I admit that this is an extremely simple example, but these ideas can be extended to much more complicated cases. Anyway we now have a controller for which unit tests can now be written as its dependencies have been isolated and fake implementations can be injected into the controller from the test class. Mission accomplished!

Monday, 7 December 2015

Unit Testing Legacy Code

Adding unit tests to legacy code can be extremely difficult. There are a number of reasons for this, such as:

  • The code base is often added to on lots of separate occasions, usually over many years, which can lead to a lack of consistency in how things are done (e.g. code conventions can change over time, new versions of the language introduce new features, etc.).
  • Lots of different developers, often of widely differing ability, work on the code.
  • The "it's working so we'd better not touch it" mantra. We've all been guilty of this; sometimes if the code is working, we just leave it be, regardless of its quality.
  • Emergency patches are applied with the promise of "we'll come back and do it properly later": of course this never happens.

This can all add up to a code base that is not particularly amenable to unit testing. Classes are often tightly coupled, with little or no use of dependency injection, and liberal use of static methods.

However legacy code is usually the code most in need of unit tests, as they allow developers to carry out refactoring safe in the knowledge that the functionality of the refactored code has remained unchanged.

In order to break this catch-22 there are a few strategies I use when adding unit tests to a legacy code base. The two main ones are:

  • The abstract factory pattern to encapsulate object creation; a factory abstraction can then be injected into the class under test to decouple it from the dependency being created.
  • Simple classes (with interfaces) to wrap static methods; the interface can be injected as above.

The aim is to introduce hook points to the code so units (e.g. a class) can be isolated and therefore unit tested.

I'll walk through a few examples in a future post of where I have applied these patterns to a real code base.