Chitika

Tuesday, June 23, 2015

Unit Testing with Fakes( Shims & Stubs )

What is Fakes: 
Microsoft Fakes is a testing framework which helps us to test code and introduce fake object for external dependencies.  This framework is mostly useful in test driven development and also can be used in functional driven development.
We can create fakes using two ways
  • Shims
  • Stubs

Stub is that part of the code which gets executed instead of the actual code. When you run unit test against a unit of code and the code consist of objects that are reference by interfaces then we use stubs to create fake objects and execute that functionality. Stub should not be used for classes they are strictly for interfaces and abstract class.
Shims are another type of fakes that execute methods and return values so that actual method that is unit tested is not broken and testing is well under control.

Pre-requisites:
·         Visual Studio 2012 Premium or above

Shim Example:
  1. Create new project, then select “Unit Test Project” under Test Category 
 

  1. Assume that you have code as below in in your project
namespace HRMS
{
    public class Employee
    {// Business Layer
        public Emp GetEmployeeDetails(int id)
        {
            DataLayer dlData = new DataLayer();
            return dlData.GetEmployeeData(id);
        }
    }

    public class Emp
    {// Model
        public int ID;
        public string Name;
        public String Location;
    }

    class DataLayer
    {// Data Layer
        internal Emp GetEmpData(int id)
        {
            return new Emp { Location = "HYD", Name = "Jhon" };
        }
    }
}

Now we will test “GetEmployeeDetails” method.
  1. Add your testable project dll to unit test project. Here “HRMS.dll” will be added to our “UnitTestWithFakes” project.
  2. Now Right click on HRMS.dll and click on “Add Fakes Assembly”,


  1. After adding it will create HRMS.Fakes.dll and HRMS.Fakes files in your project,

  1. Add using statement of your fakes dll as using HRMS.Fakes;
  2. Now create a test method as below in your test project,
        [TestMethod]
        public void GetEmployeeDetailsTest()
        {
// Everything should be under the context of Shim only by using shimsContext
            using (ShimsContext.Create())
            {
//Method to give the fake data using delegates
                ShimDataLayer.AllInstances.GetEmployeeDataInt32 = (instance, empid) =>
                    {
                        return new Emp { Location = "Bangalore", Name = "Scott" };
                    };

                Employee employeeObj = new Employee();
                Emp response = employeeObj.GetEmployeeDetails(101);
                Assert.AreSame("Scott",response.Name);
            }
        }
In the above example we are calling “GetEmployeeDetails” in that it is internally calling “GetEmployeeData”, we shim that method to replace the database call and provide dummy data.
While executing when the process reach “GetEmployee”, it will come to our delegate and whatever we pass from that it will take and return.
Now if you observe the class name will be shimmed and we get all the methods in the “AllInstances” of that class, by appending the parameters to the method, in the above case “GetEmployeeData” is the method and Parameter type is “Int32”. I.e. it is “GetEmployeeDataInt32”.
Parameters for the delegate is MethodParametersCount+1.
For testing purpose, I have tested with employee name.

Stub Example:
  1. Prepare an interface as below , in this case “IEmployee” is interface and  method is “CheckEmployeeExist
public interface IEmployee
    {
        bool CheckEmployeeExist(int EmpID);
    }
  1. Implement the interface, we can have multiple methods as well, I have taken one for sample,
    public class DataLayer : IEmployee
    {// Data Layer
        public bool CheckEmployeeExist(int id)
        {// In real time we check with data base here
            return true;
        }
    }
  1. Unit test method in test project,
      [TestMethod()]
        public void isEmployeeExist()
        {
     IEmployee iEmp = new HRMS.Fakes.StubIEmployee()
            {
                CheckEmployeeExistInt32 = (empid) =>
            {
                return false;
            }// Interface methods which are stubbed
            };

            bool response = iEmp.CheckEmployeeExist(101);

            Assert.IsFalse(response);        }
In the above the interface having the methods, which are stubbed.
We can have multiple methods with Comma (,) separation.
The base implementation of the method returns “True”, but to check we return “false” in stub method.
Shim Property:
You can shim the property of a class like below,
string name = "TestProperty";
ShimEmp.AllInstances.NameGet = (stri) => { return name; };
      The property must have get setter to make shim.


When to Use What:
Use Shims
Use Stubs
To fake the class members
To fake the interface or abstract members
To refer external referenced assemblies
Within the solution calls
When performance is not required
When performance is required
When you have static, non-virtual , sealed virtual methods
When you don’t have static, non-virtual , sealed virtual 
Not possible, when we don’t have testable methods
When we don’t have testable methods
It can fail while testing the code
It will never fail
No need of strong type
When we want strongly typed
To replace calls to .Net assemblies
Can’t be used for .Net assemblies


Note: To create fakes, the dll must have property “Copy Local: True”.

Code Samples for Redis Cache 


For Redis Cache StringGet ()  

For Cloud Configuration