Microsoft & .NETCrisp Unit Test Cases Using Microsoft Fakes

Crisp Unit Test Cases Using Microsoft Fakes

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Microsoft Fakes framework comes with Visual Studio 2012 out of the box. Microsoft Fakes framework helps you in writing crisp unit test cases. I say it as crisp because your unit test cases will test only the code that it intends to test. It helps in reducing the dependencies in the code, which have to be unit tested and it is especially effective while following test driven development (TDD).

A good unit test case is one that holds the following properties.

1. Small units – A single test case doesn’t cover a huge volume of functionality.

2. Reliable – Doesn’t change the results until there is a real code break. (No false positives).

3. Repeatable – Can be repeated n- number of times and succeeds all the time.

4. Less or no dependency – It is not dependent on things, which are bound to change.

5. >90% code coverage – Covers over 90% of the code.

Role of Microsoft Fakes

In most scenarios the properties of a good unit test case are spoiled due to the code dependencies or tight coupling in the concrete classes. Microsoft Fakes allows you to eliminate these dependencies and test only the code that is to be unit tested. It exactly isolates your code to be unit tested from its dependencies.

Microsoft Fakes provides two techniques for isolating your concrete code from other dependencies.

1. Stubs

2. Shims

I will explain about these in the following sections along with a suitable C# example. The first step in initiating the Fakes to the test project is adding a Fakes assembly. To add a Fakes assembly, right click on the reference concrete assembly in the test project and select the Add Fakes assembly option as shown in Fig 1.0. This will create the Stubs and Shims for that assembly.

Add Fakes Assembly
Fig 1.0: Add Fakes Assembly

Stubs

Stubs are the objects with custom implementation, which will be injected to the concrete class having the code to be unit tested and holding the dependency with the stubbed object. The basic requirement is that the concrete class to be stubbed needs to implement an interface and the stub will also implement the same interface. The stub object will be provided to the class containing the code to be tested through Dependency Injection.

The stubs are defined at compile time and will not have any effect on the performance of the test case at runtime.

Following is an example where the dependency is isolated by Stub technique. The class, which is to be unit tested is VehicleController.cs (CalculatePriceToFillTheTank) and it is dependent on the IAutoMobileDataService reference to fetch the Gas price of the day. Following is the source code of the concrete class.

namespace FakesStubDemo
{
    public class VehicleController
    {
        IAutoMobileDataService m_automobileService = null;
        //Object injected through the constructor
        public VehicleController(IAutoMobileDataService automobileService)
        {
            this.m_automobileService = automobileService;
        }
 
        public double CalculatePriceToFillTheTank()
        {
            //This is a service call which will return a different price daily
            double todaysGasPrice = m_automobileService.GetTodaysGasPrice();
            double tankCapacity = 37;
 
            return tankCapacity * todaysGasPrice;
        }
    }
}
 
namespace FakesStubDemo
{
    public interface IAutoMobileDataService
    {
        double GetTodaysGasPrice();
    }
}
 

Note that in VehicleController.cs the object is injected through the constructor, which makes it easy for us to inject the stub class, which will also implement theIAutoMobileDataService interface. Below is the sample unit test method, which is stubbing the actual AutomobileService.cs class.

 
namespace FakesStubDemoTest
{
    [TestClass]
    public class VehicleControllerTest
    {
        [TestMethod]
        public void CalculatePriceToFillTheTankTest()
        {
            //Build the stub mthod for getting the gas price for the day
            FakesStubDemo.Fakes.StubIAutoMobileDataService automobileService = new FakesStubDemo.Fakes.StubIAutoMobileDataService()
            {
                GetTodaysGasPrice = () =>
                    {
                        return 10;
                    }
            };
 
            VehicleController vehicleController = new VehicleController(automobileService);
 
            double actualResult = vehicleController.CalculatePriceToFillTheTank();
 
            Assert.AreEqual(370.00, actualResult);
        }
    }
}

Shim

Shims are the objects that are injected at the unit test runtime in place of other concrete objects. This technique is mainly used when the dependency code cannot be modified, like if it using some legacy code or some .NET framework class libraries. This technique will have a little overhead during the test case execution as it has to replace the actual object with the Shim at runtime. Following is a sample code where the Shim object is used for isolating the dependency.

Concrete class BillingController.cs


namespace FakesShimDemo
{
    public class BillingController
    {
        public int GetNumberOfDaysTillDueDate(DateTime dueDate)
        {
            DateTime currentDateTime = DateTime.Now;
            int gracePeriod = 2;
 
            return dueDate.Subtract(currentDateTime).Days + gracePeriod;
        }
    }
}

Test method which will execute in the Shim context.

namespace FakesShimDemoTest
{
    [TestClass]
    public class BillingControllerTest
    {
        [TestMethod]
        public void GetNumberOfDaysTillDueDateTest()
        {
            using (ShimsContext.Create())
            {
                System.Fakes.ShimDateTime.NowGet = () =>
                    {
                        return new DateTime(2013, 5, 12);
                    };
 
                BillingController billingController = new BillingController();
                int actualResult = billingController.GetNumberOfDaysTillDueDate(new DateTime(2013, 5, 14));
 
                Assert.AreEqual(4, actualResult);
 
            }
        }
    }

}

I hope this article has given a good insight about the Microsoft Fakes framework. On a general note it is always better to have the design components with least or nil dependencies between each other. This will make the code more unit testable.

Happy reading!

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories