Poor Man’s Automoq in .NET 4
So, the other day I mentioned to a coworker that I was working on a tool that would wrap moq and provide expressive test double names. I then mentioned the tool AutoMoq, and he showed me something that he was doing. It’s very simple:
[TestClass]
public class FeatureResetServiceTest
{
#region Builders
private static FeatureResetService BuildTarget(IFeatureLocator locator = null)
{
var myLocator = locator ?? new Mock().Object;
return new FeatureResetService(myLocator);
}
/// If you're going out of your way to pass null instead of empty, something is wrong
[TestMethod, Owner("ebd"), TestCategory("Proven"), TestCategory("Unit")]
public void ResetToDefault_Throws_NullArgumentException()
{
var myService = BuildTarget();
ExtendedAssert.Throws(() => myService.ResetFeaturesToDefault(null));
}
The concept here is very simple. If you’re using a dependency injection scheme (manual or IoC container), your classes may evolve to need additional dependencies, which sucks if you’re declaring them inline in every method. This means that you need to engage in a flurry of find/replace, which is a deterrent from changing your constructor signature, even when that’s the best way to go.
This solution, while not perfect, definitely eliminates that in a lot of cases. The BuildTarget() method takes an optional parameter (hence the requirement for .NET 4) for each constructor parameter, and if said parameter is not supplied, it creates a simple mock.
There are some obvious shortcomings — if you remove a reference from your constructor, you still have to go through all of your tests and remove the extra setup code for that dependency, for instance, but this is still much better than the old fashioned way.
I’ve now adopted this practice where suitable and am finding that I like it.
(ExtendedAssert is a utility that I wrote to address what I consider shortcomings in MSTest).