AutoMoq

When writing unit tests you must supply an instance of each dependency that will get called in your method being tested.

When using a mocking framework like Moq you also have the choice to supply a mocked instance of this dependency.

One of the problems of using such an approach is that every time you add or remove a dependency to the code being tested, you must go back through all your tests and refactor them to deal with this change in dependencies. One common scenario is refactoring tests to supply a new mocked instance.

If you have experienced this before, you know it can feel like a drag to go spend the extra time and modify all your existing tests.

This is where an auto mocking library like AutoMoq comes into play. (not to be confused with AutoFixture.AutoMoq)

AutoMoq will create a default mocked instance for each dependency that gets called by your test. This default mocked instance will return default values for all calls made to it’s methods unless you have defined an explicit setup on a method.

Here is a regular test using only Moq:

[TestMethod]
public void TestMethod_without_AutoMoq()
{
    // Arrange            
    var mockSomeDependency = new Mock<ISomeDependency>();
    var mockAnotherDependecy = new Mock<IAnotherDependency>();
    var mockRequestQueue = new Mock<IRequestQueue>();
 
    var objectUnderTest = new ClassUnderTest(mockSomeDependency.Object, 				       mockAnotherDependecy.Object, 
	       mockRequestQueue.Object);
			
    var testGuid = Guid.NewGuid();
 
    mockRequestQueue.Setup(mock => mock.GetNextRequest(ProcessType.Pending)).Returns(testGuid);
 
    // Act
    var result = objectUnderTest.AssignRequest(ProcessType.Pending);
 
   // Assert
   Assert.AreEqual(testGuid, result);
}

Here SomeDependency and AnotherDependency are dependencies that get called when GetNextRequest is invoked, but for which we do not care what values are returned. Even though we are not using their return values, we must still define mocks for these dependencies or we will get a null reference exception.

And here is how you would convert this test to use AutoMoq:

[TestMethod]
public void SameTest_with_AutoMoq()
{
    // Arrange    
    var mocker = new AutoMoqer();    
    var testGuid = Guid.NewGuid();
 
    mocker.GetMock<IRequestQueue>()
				  .Setup(mock => mock.GetNextRequest(ProcessType.Pending))
										.Returns(testGuid);
 
    var objectUnderTest = mocker.Resolve<ClassUnderTest>();
 
    // Act
    var result = objectUnderTest.AssignRequest(ProcessType.Pending);

    // Assert
    Assert.AreEqual(testGuid, result);
}

AutoMoq not only saves on the length of the test (as you don’t have to specify all dependencies), it will also cut on the time needed to refactor your tests when changes are introduced.

While the test is definitively shorter and less cluttered, the real magic comes when you add another dependencies to ClassUnderTest. In the AutoMoq test, you don’t have to do any refactoring unless you need to specify an explicit value for a method on the dependency.

Note about MEF and AutoMoq

Note that AutoMoq inject’s dependencies supplied in the constructor. If you use MEF, dependencies injected by using attributes on properties will not be managed by AutoMoq, only dependencies injected by using an ImportingConstructor.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s