Tuesday, December 28, 2010

Creating an Automocking container for Moq using Unity

Auto mocking allows you to get object of the type you want to test without setting up mocks by hand. Using an auto mocker you can create the mock classes with dependencies and the container will automatically resolve the dependencies for you. The auto mocker will also keep track of all the mocks it creates, and allows you to retrieve them if you need to stub a specific behavior. In this post we'll se how to create an auto mocking container for Moq using Unity.
The container implementation mainly has 2 methods GetMock and Create.
The GetMock is used to get the Mock of the object so that you can setup expectations and behaviours and later use this for verification.
public Mock GetMock(params object[] constructorParameters) where T : class
{
    var _mockedObject = (IMocked)this.Create(constructorParameters);
    return _mockedObject.Mock;
}

The Mock method is responsible for creating the mock and resolving dependencies
public T Create(params object[] constructorParameters) where T : class
{
    if (!_container.IsRegistered())
    {
        var mockedType = new Mock(constructorParameters).Object;
        var resolvedType = _container.BuildUp(mockedType);
        Register(resolvedType);
    }
    return _container.Resolve();
}

Test methods
Customer customer = CreateMockCustomerWithOrder();
var orderRepository = _mockContainer.GetMock<IOrderRepository>()
        .Setup(o => o.GetByCustomer(customer)).Returns(customer.Orders);

_mockContainer.Register<IOrderRepository>(_mockContainer.Create<IOrderRepository>());
ICustomerRepository customerRepository = _mockContainer.Create<CustomerRepository>();

customerRepository.Add(customer)

The UnityMockContainer code used in this sample.
public class UnityMockContainer
{
    IUnityContainer _container;

    public UnityMockContainer()
    {
        _container = new UnityContainer();
    }

    public Mock GetMock(params object[] constructorParameters) where T : class
    {
        var _mockedObject = (IMocked)this.Create(constructorParameters);
        return _mockedObject.Mock;
    }

    public T Create(params object[] constructorParameters) where T : class
    {
        if (!_container.IsRegistered())
        {
            var mockedType = new Mock(constructorParameters).Object;
            var resolvedType = _container.BuildUp(mockedType);
            Register(resolvedType);
        }
        return _container.Resolve();
    }

    public T Create(System.Linq.Expressions.Expression<Funcbool>> expression) where T : class
    {
        if (!_container.IsRegistered())
        {
            var mockedType = Moq.Mock.Of(expression);
            var resolvedType = _container.BuildUp(mockedType);
            Register(resolvedType);
        }
        return _container.Resolve();
    }

    public void Register() where TTo : TFrom
    {
        _container.RegisterType();
    }

    public T Resolve()
    {
        return _container.Resolve();
    }

    public void Register(TFrom instance)
    {
        _container.RegisterInstance(instance);
    }
}

No comments: