Unit Testing using Fakes

Microsoft Fakes, which requires Visual Studio 2012 Premium, is a fully featured mocking framework used for isolating the code under test by replacing the other parts of the application with Stubs and Shims. This is very useful in testing only the small portion of the code under test without worrying about the other parts of the application or component even if it fails. The Microsoft Fakes can Shim any .NET method, including non-virtual and static methods in sealed types.

Stubs

The Stub type makes it easy to test code that consumes interfaces or non-sealed classes with overridable methods. The default behavior can be dynamically customized for each member by attaching a delegate to a corresponding property of a Stub.

To use Stubs, each component of the application should depend only on interfaces and not on any other component. The Stub replaces another class with a substitute that implements the same interface.

Let's build a sample application to calculate the total price for an item based on the quantity and unit price. Let us start with the interface and a class with a method, but no implementation in it except throwing the not implemented exception:

    public interface ITotalPrice
    {
        decimal UpdateTotalPrice(int value);
    }

     public class TotalPrice : ITotalPrice
    {

        public decimal UpdateTotalPrice(int value)
        {
          throw new NotImplementedException(); 
        }
    }

Create a unit Test Project and add a unit test method for UpdateTotalPrice method. We include an assert method to call and verify the output of the UpdateTotalPrice method. The test would fail with the expected exception, NotImplementedException.

Stubs

To implement the method and test it, there are a few additional calls to be made to calculate the price based on quantity, update total price, and to get the total price. To do this, define a repository with a new interface and with methods:

    public interface IRepository
    {
        void UpdateTotalPrice(int value);
        decimal GetTotalPrice();
    }

Now modify the test to take the repository in the constructor of the TotalPrice object. Use the Fakes framework to achieve this. Open the references of the Unit Test Project, select the Unit Test Project reference and right-click on the reference.

Stubs

Select the Add Fakes Assembly option from the Context menu. This will immediately add a reference to the Microsoft.QualityTools.Testing.Fakes assembly and then few seconds later, it will add a reference to a fake version of assembly.

Stubs

Open the test code and update the test with a Stub repository as follows:

        [TestMethod]
        public void TestUpdateTotalPrice()
        {

            decimal unitPrice = 10.5M;
            decimal totalPrice = 0.0M;
            IRepository repository = new TTotalPrice.Fakes.StubIRepository()
                    {  
                        GetTotalPrice = () => 
                        {
                            return totalPrice;
                        },
                        UpdateTotalPriceInt32 = value =>
                            {
                                totalPrice = unitPrice * value;
                            }
                    };

            ITotalPrice totPrice = new TotalPrice(repository);
            var actualTotalPrice = totPrice.UpdateTotalPrice(2);

            Assert.AreEqual(21, actualTotalPrice);
        }

The new fake assembly that was generated contains the Stub version of the classes, both StubIRepository and StubITotalPrice. If the test is built and run, it would fail again because of the exception. There is no implementation for the TotalPrice class, but we can implement that as follows:

    public class TotalPrice : ITotalPrice
    {
        IRepository _repository;

        public TotalPrice(IRepository repository)
        {
            _repository = repository;
        }

        public decimal UpdateTotalPrice(int value)
        {
            _repository.UpdateTotalPrice(value);
            return _repository.GetTotalPrice();

            //throw new NotImplementedException(); 
        }
    }

Now build the project and run the test. The test will pass now as expected.

Although Stub types can be generated for interfaces and non-sealed classes with overridable methods, they cannot be used for static or non-overridable methods. To address these cases, the Fakes framework also generates Shim types.

Shims

A Shim modifies the compiled code at runtime to replace a method call. The method call can be to any of the assemblies that cannot be modified, such as .NET assemblies. We can use Shims to isolate the code from assemblies that are not a part of the solution.

Difference between Stubs and Shims

 

Shims

Stubs

Performance

Because of rewriting the code at run time, it runs slow.

No performance overhead

Static methods and sealed types

 

Stubs are used only to implement interfaces. Stub types cannot be used for static methods, non-virtual methods, methods in sealed types, and so on.

Internal types

Can be used

Can be used

Private methods

Can replace calls to private methods if all the types on the method signature are visible.

Can replace only visible methods.

Interfaces and abstract methods

Cannot instrument interfaces and abstract methods.

Provides implementation of interfaces and abstract methods.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.76.72