Isolating code during testing with Microsoft Fakes (Shims)
- Transfer
I finally abandoned Java and went into .Net and every time I talked about unit tests I recalled that there are more possibilities for Java.
And in 2012, the studio added the ability to make any objects mock. Absolutely any, even system. Under the cut is a translation of an article from MSDN (translated only by shim, because stubs are of little interest).
Microsoft uses the term “shim”, I will not try to translate it, let it be so - shim.
What are shims?
Microsoft Fakes helps isolate the tested code with two ways - shims and stubs.
Shims modify the compiled code in runtime, so that a method call is replaced by a call to the code you wrote. Shims can be used to replace assembly calls that you cannot control, such as .Net Framework assemblies.

The choice between stubs and shims
Usually a project in VS is developed as a separate component and there is a desire to use stubs or shims for used objects from other projects in the solution or external assemblies to which the project refers.
Try to use stubs for the code that is inside the solution, and shims for external assemblies. It is considered good practice to decompose elements by highlighting interfaces, which allows the use of stubs, but external assemblies such as System.dll usually do not have this decomposition, so you should use shims.
Usage
Imagine your component has a DateTime.Now call:
// Code under test:
public int GetTheCurrentYear()
{
return DateTime.Now.Year;
}
During the test, you want to make the Now property pwm, because the original always returns different values.
To use a shim, you do not need to modify the code or write it in a certain way.
1. Adding a fake assembly
In Solution Explorer, open the references of your project and select the assembly that contains the classes that you want to replace. The DateTime class is in the System.dll assembly. and select “Add Fakes Assembly” from the context menu.
2. Using shims inside a ShimsContext
[TestClass]
public class TestClass1
{
[TestMethod]
public void TestCurrentYear()
{
int fixedYear = 2000;
// Shims can be used only in a ShimsContext:
using (ShimsContext.Create())
{
// Arrange:
// Shim DateTime.Now to return a fixed date:
System.Fakes.ShimDateTime.NowGet =
() =>
{ return new DateTime(fixedYear, 1, 1); };
// Instantiate the component under test:
var componentUnderTest = new MyComponent();
// Act:
int year = componentUnderTest.GetTheCurrentYear();
// Assert:
// This will always be true if the component is working:
Assert.AreEqual(fixedYear, year);
}
}
}
Shim class names begin with the Fakes.Shim prefix added to the original names.
In the example, the shim is used for the static method, to use the shim for the non-static method, add AllInstances between the type name and the method name:
System.IO.Fakes.ShimFile.AllInstances.ReadToEnd = ...
Shims can also be created for specific objects, designers, properties.
If this translation turns out to be interesting to people, then I will do a translation of the next article, which gives examples of the use of shims for all cases.