Easier Mock Construction in .NET

We’re currently using Moq as our mocking library on an ASP.NET MVC application. Moq has been working out pretty well, but building mock objects is a little cumbersome. We’re using StructureMap heavily, which leads to frequent updates to the constructors which StructureMap relies on to compose our object graph. Moq requires you to match the arguments of your mock constructor to the parameters of the mocked class’s constructor. Every time we mock an instance of a class we have to figure out how many arguments that class’s constructor takes and pass a default value in for each. To make matters worse, when we add arguments to a constructor, we have to move from failing test to failing test, adding null arguments to the mock constructor to fix runtime errors in our NUnit SetUp.

To address these issues, we threw together a function to dynamically determine the arity of a mocked class’s constructor (which we assume only has one) and invoke the mock constructor appropriately. Since updating our tests to use the function below, we haven’t had to update a single SetUp in response to a constructor signature change.


protected Mock<T> NewMock<T>() where T : class
{
    var type = typeof(T);
    var constructors = type.GetConstructors();
    if (constructors.Length == 0) constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    if (constructors.Length == 0) return new Mock<T>();

    var constructor = constructors[0];
    var parameters = constructor.GetParameters();

    var objects = parameters
        .Select(p => p.ParameterType.IsValueType ? Activator.CreateInstance(p.ParameterType) : null)
        .ToArray();
    var constructorInfo = typeof(Mock<T>).GetConstructor(new Type[] { typeof(object[]) });
    return (Mock<T>)constructorInfo.Invoke(new object[] { objects });
}
Conversation
  • Aaron says:

    Why do you mock so many concrete classes that you felt compelled to do this? Is there a reason not to just use interfaces and mock them?

  • Hi Aaron,

    In most cases we simply don’t need interfaces, and using classes directly is more convenient. If we don’t yet need to exploit polymorphism in part of our application or we’re not designing an API for public consumption, we can make progress more quickly without having to keep a large number of interfaces in sync.

    Since we follow the single responsibility principal and rely heavily on composition (provided by StructureMap), we tend to have pretty populous object graphs. Avoiding a proliferation of otherwise unnecessary interfaces is a time savings.

    We’ve been creating interfaces lazily when needed, a luxury afforded by Moq’s ability to mock classes. That said, if Moq wasn’t able to mock classes, we’d be using interfaces more frequently, as we have when using EasyMock on past Java projects.

    Drew

  • I haven’t seen the code, but you shouldn’t be digging this deep. If you need the DI framework to assemble the objects, then these are more integration tests and you should work with mostly real objects. If you’re unit testing individual classes, then you shouldn’t be using the DI framework to assemble them.

    I won’t go into the classes/interfaces issue for now.

  • Hi Steve,

    We’re not using DI in our tests, we’re using it in our application.

    Drew

  • Comments are closed.