Testing static methods, or to be more specific, extensions methods is imposssible with the standard mocking frameworks like Moq ( which I prefer ) and RhinoMocks. There do exist more sophisticated frameworks like TypeMock and JustMock which can do the job for you. I have been pretty contended with the simplicity of Moq. Also, when you want to mock static methods or do some other magic, many a times, it means that there is something wrong with the design. With right dosage of proper design, decoupling objects, dependency injection and simplicity, you can write testable code without requiring sophisticated tools.

I did come across Microsoft Fakes that is available with Visual Studio 2012. It is built on top of ( and to replace ) Microsoft Moles that was available previously. In a project that I was writing, the simplest design was in using extension methods ( which, in C#, are effectively static methods). Testing them posed a problem. This was a good time as any to try out Microsoft Fakes.

MicrosoftFakes

Starting with the framework was pretty simple. Add the fake assembly for the assembly to be “shimmed” in the Test Project. Using Visual Studio Ultimate ( which is required) you can just right click on the assembly reference and click on “Add Fakes assembly.” This creates and adds a reference to the fake assembly.

Now, we can easily add a shim that replaces the actual extension method. A standard test would look like below:

[TestFixture]
public class ToggledFeatureTests
{
    [Test]
    public void ShouldReturnOneWhenToggledFeatureIsOn()
    {
        var toggledFeature = new ToggledFeature();

        using (ShimsContext.Create())
        {
            Fakes.ShimToggledExtensions.IsOnIToggled = toggled => true;
            Assert.That(toggledFeature.SomeProcessing(), Is.EqualTo(1));
        }
    }
}

The extension method being shimmed here is

public static bool IsOn(this IToggled toggledFeature)
{
    var appSettingKeyForToggledFeature = string.Format("{0}.{1}", "Toggler", toggledFeature.GetType().Name);
    return ConfigurationManager.AppSettings[appSettingKeyForToggledFeature] == "true";
}

The shims have to be used with a ShimsContext using block as seen in the test code above. When the context is disposed, the method intercepts are reset to normalcy.

The fakes generated by Fakes follow some naming conventions. Without going into the details, the original type ToggledExtensions is replaced with Fakes.ShimToggleExtensions and the IsOn method in it which takes in a IToggled ( like a normal static method would, but in this an extension method) is called IsOnIToggled. The shim being provided is the lambda toggled => true. That is return true for any IToggled instance. Then there is a pretty standard assert.

There are some disadvantages with Microsoft Fakes. First and foremost, it might lead to bad code. In certain situations,tools like this help you to test code without having to make severe changes to it (like wrapping static method calls in a class ) or designing it in a complicated way just to support testing. But like already mentioned, most of the times, untestable code indicates something much deeper - code smells, bad design etc. You need to make a conscious decision when to use these feature of Microsoft Fakes. Secondly, Fakes requires Visual Studio Ultimate. Last, when using shims, the tests fail when running from Resharper ( 7.0 ) provided runner. This is a huge deal as my entire team uses Resharper and the tests must pass with the runner. There is a bug filed with JetBrains and I am hoping it will be fixed soon. If you use the Nunit Test adpater and the VS 2012 Test runner, the tests pass, however.

I haven’t used the stub facilities provided by Microsoft Fakes and I am not sure it will be needed, considering that Moq should suffice. Shims, however, I see myself using in certain circumstances, especially once the Resharper bug is fixed.