Wednesday, June 4, 2014

What is faking framework?

Microsoft faking is an isolation(mocking) framework that allows us to mock the static,sealed method without rewriting any implementation code. The mocking is primarily used in unit testing. An object under test may have dependencies on other (complex) objects to resolve that dependency in unit testing we need to mock. If we have dependency of other component in project, then we need to implement mocking for automated unit test cases.The benefits of MS fakes are easy to write unit tests and less refactoring time, although at the expense of maintaining tightly-coupled code.

Available frameworks for mocking.

There are lots of framework available for mocking like 
  • MOQ
  • Rhino
  • Moles
  • Faking (new in MS VS 2013)

Comparison among MOQ, Moles, Rhino and MS Faking framework

S. No.
Feature
MOQ
Moles
Rhino
MS Faking framework
1
Licensing
Free
Free(MS VS Gallery)
Free
Free(VS 2013 Ultimate and Premium)
2
Can Mock:
Interface
Yes
Yes
Yes
Yes
3
Abstract class
Yes
Yes
Yes
Yes
4
Event
Yes
Yes
Yes
Yes
5
Exception
Yes
Yes
Yes
Yes
6
Concrete class virtual methods/properties
Yes
Yes
Yes
Yes
7
Concrete non virtual member
No
Yes
No
Yes
8
Static Class
No
Yes
No
Yes
9
Sealed Class
No
Yes
No
Yes
10
Protected Virtual
No
Yes
No
Yes
11
Supports callback on mock method
Yes
Yes
Yes
Yes
12
Supports multithreading exception
No
Yes
Yes
Yes
13
Supported version
3.5/4.0
2.0/3.5/4.0
1.1/2.0/3.0/3.5
4.5
14
Support Linq
Yes
Yes
Yes
Yes

Background of Faking Framework

The fake framework in VS 2013 is next generation of moles and stubs and will eventually replace the Moles features. 
  • A stub replaces a class with a small substitute that implements the same interface. To use stubs, we have to re-design our application so that each component depends only on interfaces, and not on other components. By "component" we mean a class or group of classes that are designed and updated together and typically contained in an assembly.

  • A shim modifies the compiled code of our application at run time so that instead of making a specified method call, it runs the shim code that our test provides. Shims can be used to replace calls to assemblies that we cannot modify, such .NET assemblies. 

Integrate VS 2013 with MS Fake Framework

Fake framework have two components
  1. Stub's.
  2. Shims.

When we are mock object or methods using stub's we need to design our class structure according to stub's rule,each class should inherited to interfaces.
Integration with Visual Studio
To start writing unit test cases using MS Fake we need to add Faking framework library.
Right click on Add reference of test project > click on browse tab >click on browse button > give that path to add faking dll
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PublicAssemblies\Microsoft.QualityTools.Testing.Fakes.dll". 
Note:
MS Fakes framework is only available in Ultimate and premium edition as of now.Compare chart of VS product

The integration with Fakes with Visual Studio 2013 is brilliant. To create a "fake" of an assembly, we needs to just right click on the references and click the option "Add Fake Assembly" in test project.

When we add a fakes assembly in our test project by right clicking on the reference assembly and clicking the "Add Fakes Assembly" option, visual studio adds the following files.

  1. A new "Fakes" folder is created with a .fakes files created in it. For example, if we are creating fakes for "System.Configuration", a file called "System.Configuration.fakes" will be created.
  2. A new "FakesAssemblies" folder is created with three files created.
1. originalAssembly.assemblyversion.Fakes.dll
2. originalAssembly.assemblyversion.Fakes.xml
3. originalAssembly.assembly.Fakes.fakesconfig. 
So, for "System.Configuration" assembly the files generated would be System.Configuration.4.0.0.0.Fakes.dll,System.Configuration.4.0.0.0.fakes.xml and System.Configuration.4.0.0.0.Fakes.fakesconfig 
Visual Studio also adds a reference to the generated assembly in the "FakesAssemblies" folder.The "FakesAssemblies" folder and all the files in it are generated whenever the project is compiled. This is important because if we are adding fakes for assembly for a changing component, the generation of FakesAssemblies will ensure that all changes are reflected in the generated assembly. 
After adding successful faking dll(s) system will add one more dll named mscorlib.4.0.0.0.Fakes.
Note that mscorlib.4.0.0.0.Fakes assembly contains a special type called Shims. Shims are strongly typed wrapper that allows to replace .NET types with delegates.

Structure of a unit test project:

Structure of Unit test project looks like below screen.
Left part of screen is test execution result.
Right part of screen is structure of test project.
Middle part of screen is actual unit test case.
To execute test cases just right click of test method and choose "Run test" or go to Test > Run >All test


Structure of Unit test case

[TestClass]
public class ThingTest
{
        // Setup

        // Exercise

        // Verify

        // Teardown

    [TestMethod]
    public void TestSomething()
    {
        
    }
}

Create Bootstrap 



Create Setup ( all required db object) to execute Test case.


How to use Shims



Attributes of unit test method

MSTest Attribute
Purpose
[TestMethod]
Identifies of an individual unit test
[TestClass]
Identifies of a group of unit tests, all Tests, and Initializations/Clean Ups must appear after this declaration
[ClassInitialize]
Identifies a method which should be called a single time prior to executing any test in the Test Class/Test Fixture
[ClassCleanup]
Identifies a method in to be called a single time following the execution of the last test in a TestClass/TestFixture
[TestInitialize]
Identifies a method to be executed each time before a TestMethod/Test is executed
[TestCleanUp]
Identifies a method to be executed each time after a TestMethod/Test has executed
[AssemblyInitialize]
Identifies a method to be called a single time upon before running any tests in a Test Assembly
[AssemblyCleanUp]
Identifies a method to be called a single time upon after running all tests in a Test Assembly
[Description]Description about test method.
[TestCategory]Defines the category of test method, it could be positive or negative.
[DataSource]
Define the data source of test method by which method gets the data and execute the logic.
It could be XML,CSV or Database
[DeploymentItem]
Specify a file or directory that should be deployed along with the assemblies before running a test.
Attach this attribute to a test class or test method. We can use multiple instances. 

Modifications required to Project 

If we mock the object or class by using "Shims" then no need to change anything in solution, but when we use "Stubs" then we have to re-design structure of solution inherits all the classes from interface.

Challenges/Issues and possible workarounds


  • When we adds the fake assembly of main project exe/dll (which we want to write unit test case) the "Project.fakes" file add in Fakes folder into test project. Might be possible its throw an error, if an error thrown by system during build, the cause of issue could be test projects fakes gives compilation error. The exact error is given below.

"Could not resolve this reference. Could not locate the assembly "System.Configuration.4.0.0.0.Fakes". Check to make sure the assembly exists on disk."
The error would go away if I added the FakesAssemblies folder in Source control.after detailed analysis found the reason of error happened was because the “Build action” for the ".fakes" file added to the project was not set correctly. These files should have the build action set to "Fakes" instead of "None".


 before set build action ="Fakes" it was


  • MS-Fakes work only Ultimate or premium edition,i have install professional edition and found it not works.
  • Open AssemblyInfo.cs of main project  and add [assembly: InternalsVisibleTo("UnitTestProject")] as below screen

  • When we play with external data source like XML to execute our test case we need to add reference of "System.Data" by right click on Reference > Add reference otherwise we can not read data from xml file.
  • After code was written to get the test values from external data source, I could not get the result like below screenshot. Following are the common issues that may encounter and here is the solution:
    Issue: The unit test adapter failed to connect to the data source or read the data.
Solution : Go to the Solution Explorer, add new item into solution, then select "Test Settings" from the left menu, then add a new test setting.

In the "Test Settings" window, select "Deployment" from the left menu, then check the "Enable Deployment" check-box and click on apply.


If problem still persist,then go to Solution Explorer, locate  test data XML file and then open the file properties. Make sure the "Copy to Output Directory" property is NOT set to "Do not copy", make it either "Copy always" or "Copy if newer". like below screen

After doing all above steps,it works.

Conclusion

Unit testing is a major component of every project. The early feedback receive from our tests help us feel confident that we didn’t introduce new bugs, and that we gave to QA actual working code.Faking framework helps us to mock the dependent complex module like email server,database layer etc and we don't need to implement dependency injection and don't need to create fake by inheritance.Every faked instance looks and feels like an instance of the faked type.After comparing all others mocking frameworks available in market MS faking framework gave us to more feature rather than others.Hence it is highly recommended to use MS fakes into project to gave the better delivery of the code.