Automocking can greatly reduce the friction of keeping unit tests current in an ever changing code base.  For more information, please see these blogs posts on automocking with JustMock:

Background

One of the issues that can arise with automocking is when the class being constructed (the system under test) has many constructors.  Different automocking frameworks have different rules as to which one to use, but more often than not, it’s not the one that you want it to use!  What’s needed is the ability to tell the framework which constructor to use, but still gain the benefit of not having to create each of the mock objects explicitly.

The Solution

JustMock has added the capability to select a specific constructor while creating the instance of the system under test. 

The System Under Test

To show this new feature, I created a simple class that has multiple constructors, as shown in Listing 1.

public class ManyConstructors
{
 private IFoo _foo { get; set; }
 public ManyConstructors(IFoo foo)
    {
        _foo = foo;
    }
 public ManyConstructors()
    {
        _foo = new Foo();
    }
 public string UserDependency()
    {
 return _foo.GetData();
    }
}

Listing 1 – The System Under Test

This simple class has two constructors – the default constructor that doesn’t take any parameters, and uses a concrete class (shown in Listing 2) as the dependency.  The other constructor uses dependency injection.  Of course, it’s much better to use dependency injection, but legacy code is what it is, and we don’t always get to work with great code!

public class Foo : IFoo
{
 public string GetData()
    {
 return "Bar";
    }
}
public interface IFoo
{
 string GetData();
}

Listing 2 – The Foo dependency and the IFoo interface

The Original Test

As a refresher on automocking, we can write our test as shown in Listing 3.  We use the generic MockingContainer class to create an instance of the ManyConstructors class, and we verify that the class is indeed using the concrete Foo class by asserting that the UserDependency() method returns the string “Bar”.

[Test]
public void ShouldCreateAutoMock()
{
    var container = new MockingContainer<ManyConstructors>();
    Assert.AreEqual(container.Instance.UserDependency(), "Bar");
}

Listing 3 – The original automocking test

But what if we want to use the constructor that uses dependency injection?

Selecting the Constructor

Selecting the proper constructor is as simple as passing the the correct types when instantiating the system under test, as shown in Listing 4.

[Test]
public void ShouldCreateAutoMockChoosing()
{
    var container = new MockingContainer<ManyConstructors>(typeof(IFoo));
 string result = "Phil";
    container.Arrange<IFoo>(x => x.GetData()).Returns(result);
    Assert.AreEqual(container.Instance.UserDependency(), result);
}

Listing 4 – Selecting the constructor

But wait…

You might be wondering “Doesn’t this eliminate the benefit of automocking?”.  The answer, of course, is “It depends”. Smile  One of the main benefits of automocking is reducing the amount of set up time in your tests.  This is still true.  You don’t need to explicitly create the mocks for the dependencies, and you only need to arrange the mocks that matter for the execution of your test.

We do lose the ability for the container to automatically adjust to a changing code base.  In our example, if the constructor that takes IFoo as a parameter is modified to take another parameter, our test will fail, since the constructor will not be able to create the system under test.  As always, the best course of action is to use critical thought when deciding a testing strategy.

Summary

When your classes have multiple constructors, but you can still gain efficiencies by using automocking, JustMock allows you to choose the correct constructor when you instantiate your system under test.  This doesn’t come without a downside, as you lose some of the elasticity of your tests.  But JustMock has yet again provided additional mechanisms to handle your various testing needs.

 

JustCode download banner image


Japikse
About the Author

Phil Japikse

is an international speaker, a Microsoft MVP, ASPInsider, INETA Community Champion, MCSD, CSM/ CSP, and a passionate member of the developer community. Phil has been working with .Net since the first betas, developing software for over 20 years, and heavily involved in the agile community since 2005. Phil also hosts the Hallway Conversations podcast (www.hallwayconversations.com) and serves as the Lead Director for the Cincinnati .Net User’s Group (http://www.cinnug.org). You can follow Phil on twitter via www.twitter.com/skimedic, or read his personal blog at www.skimedic.com/blog.

 

Comments

Comments are disabled in preview mode.