Fakes, Stubs, Shims, Moles and how to verify them?

Background

If you have been following my posts here and here before you probably know that when I have to I use Moles from Microsoft Research. So the other day a friend of mine mentioned this new cool thing called Fakes, Stubs and Shims in Visual Studio 11 so I decided to look into that.

The first thing I actually did was to ask the following question on Twitter because I was curious to see if Moles and Fakes were similar:

Ok so Fakes in VS 11 are derived from Moles. My next question to Peter was one I’ve been thinking about alot lately:

So Microsoft are looking into adding verify support to Fakes, great!!! this means that you don’t have to use this hack going forward 🙂 Thanks Peter for that fast feedback!

For all you using Moles this hack will still apply. And for all you SharePoint developers out there; YES this is for you guys because you need to be doing more TDD!

My next step was to create a bootable vhd with Windows 8 Consumer Preview and Visual Studio 11 using my preferred method here and start hacking away.

Step 1

Get up to speed with Fakes, Stubs, Shims by reading “Using shims to isolate calls to non-virtual functions in unit test methods” found here; go on I’ll wait until you’re finished.

You’ll probably end up with a test method looking like the one shown below:

    [TestClass]
    public class Y2KCheckerTests_Step1
    {
        [TestMethod]
        [ExpectedException(typeof(ApplicationException))]
        public void Check_WhenCalledWithTheDate_2000_1_1_ThenApplicationExceptionIsThrowned()
        {
            using(ShimsContext.Create())
            {
                ShimDateTime.NowGet = () => { return new DateTime(2000, 1, 1); };

                Y2KChecker.Check();
            }
        }
    }

Well this is all fine, but what if you have a thousand tests that want to detour DateTime.Now? If you read my previous post here I introduced a Testable object that encapsulates behaviour.

Step 2

So the next step is to encapsulate this into a Testable object that I call Y2KShimDateTime like the code below shows:

[TestClass]
public class Y2KCheckerTests_Step2
{
    [TestMethod]
    [ExpectedException(typeof(ApplicationException))]
    public void Check_WhenCalledWithY2KShimDateTime_ThenApplicationExceptionIsThrowned()
    {
        using (ShimsContext.Create())
        {
            Y2KShimDateTime shim = new Y2KShimDateTime();

            Y2KChecker.Check();
        }
    }
}

public class Y2KShimDateTime
{
    public Y2KShimDateTime()
    {
        ShimDateTime.NowGet = () => { return new DateTime(2000, 1, 1); };
    }
}

Wow now we’re getting somewhere. We can reuse our Y2KShimDateTime in all our test methods. But hey what if we really just want to verify that a specific method has been called? You could just add some counter to the Y2KShimDateTime and call a property like the recommendation here.

Step 3

I use Moq to Mock my code because it’s simple and I love the way I can control return values with setups but mostly I love the way I can verify that a certain method was called with a specific value! If you haven’t looked at Moq yet I strongly encourage you to do so!

To accomplish this with Fakes, Shims or Moles you will need to trick Moq a bit (a hack I know). First of all let’s take a look at my verifiable Y2KShimDateTime class called VY2KShimDateTime.

public class VY2KShimDateTime
{
    public void InitFake()
    {
        ShimDateTime.NowGet = () =>
        {
            return VNowGet();
        };
    }

    public virtual DateTime VNowGet()
    {
        return new DateTime();
    }
}

The first part of the trick is to move the initialization of the detour from the constructor to a public method. This enables us to initialize the detours from Moq as you will see soon. The next thing is to create a public virtual method (VNowGet in this case) that will be called by Moq. There you have it! Easy enough?

Lets see how we use the VY2KShimDateTime from Moq.

using (ShimsContext.Create())
{
    Mock mock = new Mock();
    mock.Object.InitFake();
    mock.Setup(v => v.VNowGet()).Returns(new DateTime(2000, 1, 1));

    Y2KChecker.Check();
}

As you can see from the highlighted row above we’re initializing our detours after we create our mock this way we can be sure our detours will work. And now we can use the usual setup from Moq to Control what our detour will return. Brilliant don’t you say?

Let’s throw a verify into this equation and look how that looks.

using (ShimsContext.Create())
{
    Mock mock = new Mock();
    mock.Object.InitFake();
    mock.Setup(v => v.VNowGet()).Returns(new DateTime(1, 1, 1));

    Y2KChecker.Check();

    //Uncomment line below to see verify that mock.Verify throws correct message
    //Y2KChecker.Check();

    mock.Verify(v => v.VNowGet(), Times.Once());
}

In this case we’ll have to supply a date other than Y2K because otherwise we’ll get an exception but as you can see in the verify method we verify that DateTime.Now is called only once. If I would to uncomment the second Y2KChecker.Clean(); call the verify on our mock would throw an exception.

Summary

I’ve showed how to create verifiable Fakes, Stubs and Shims (works for Moles as well) using a small hack. I use this approach daily when I work with Moles because I really like the combination of Moq verify and setup and Fakes/Moles isolation and detouring.

Hopefully Microsoft will incorporate this in a near future in Fakes but until then give this a try.

All code can be downloaded from GitHub here.

Cheers,

Hugo

How I used Moles in a real life BizTalk scenario

Background

When you’re building BizTalk applications with TFS Build and then doing some deployment you pretty much end up with the situation where you DO NOT want to create BizTalk applications manually or automatically from some text-file. There is actually a place where this information is stored and it’s called a Bindings File.

A Binding File contains information specific for a BizTalk application and it’s in XML. If you really are into details I encourage you to read this article on MSDN. In short you should use Binding Files and only Binding Files as a part of your automatic deployment process. Thanks to Johan Hedberg and Mikael Håkansson for pointing this out.

Hey this has nothing to do with Moles! Be patient and start by installing Moles here are the free download links from the Visual Studio Code Gallery:

Moles

Moles is a lightweight framework for test stubs and detours in .NET that is based on delegates. Moles may be used to detour any .NET method, including non-virtual/static methods in sealed types. Moles is freely available on Visual Studio Gallery or bundled with Pex.

That’s what Microsoft Research introduces Moles as so now back to my real life scenario.

Writing extensions to the BindingInfo class with Moles

So there is actually a class in the assembly Microsoft.Biztalk.Deployment.dll that wraps the structure of a Binding File into a .Net class. So my thought was to write some helpful extensions methods that could help me in retrieving the name of the BizTalk application configured in the Binding File.

Are you still with me?

If we take a closer look at the BindingInfo class:

image

The BindingInfo has a default constructor that takes no parameters and then there is a LoadXml method that takes a string to the path of the Binding File. So now I have several options:

  • I could create my own implementation of BindingInfo and create a subclass that I could mock
  • I could use any other Mocking framework, like moq
  • I could use strictly integration tests (tests that use external resources) to test my extension methods

In this case I decided to use Moles because I like to try out new stuff. (Mind you this is not the most common scenario on when to use Moles but just bare with me)

Have you installed it yet? Good lets move on.

Adding a reference to a Moled assembly

Right click any referenced assembly and choose Add Moles Assembly like so:

image

Rebuild your test project and you’ll find two new items added to your project.

image

The first new item is a reference to an assembly that is the Moles representation of (in this case) Microsoft.BizTalk.Deployment.Moles.

And the second new item is a .moles file is a simple XML file telling Moles which Moles representation should be created at build time. This is how my Microsoft.BizTalk.Deployment.moles looks like:

image

This can have implications on build performance that I will try to write another post about soon.

Now you have everything in place to start writing your tests right? Let’s goooo! First of all you’ll need to decorate all your test methods where you’re going to use Moled objects with the HostType attribute. I use my own code snippet for this (based on the TestMethod code snippet already in Visual Studio).

image

And then start writing test cases. But how do you find your Moled objects? Well I usually find my Molable object using the complete namespace to the stuff you want to Mole + Moles + M + intellisense. Look at the example below:

image

If you use complete namespace to the stuff you want to Mole + Moles + S + intellisense then you’ll get the stubbable instances instead like so:

image

In my scenario I wanted to make sure that when the LoadXml method is called on any BindingInfo object in my tests it doesn’t read stuff from my disk but it just returns or initializes any properties I’m interested in. This is how I would write this:

image

A quick recap:

  • MBidingInfo was found using the complete namespace to the stuff you want to Mole + Moles + M + intellisense method mentioned above.
  • AllInstances means that for all instances I want to replace some method with my own delegate.
  • LoadXmlString is the method I want to Mole. After a while using Moles you’ll see that methods have there original name followed by the Type of the input parameters if any.
  • Then I’ve written my delegate declaration and body that takes in two parameters called instance and path.

To make this even more interesting you can add Asserts in the delegate (I say you can, I’m not sure this is a good practice) like the following picture:

image

Now I can continue writing my test as if my BindingInfo objects had loaded the xml from file. But how can I verify that some Moled method has been called? Well Moles doesn’t intend to provide you with Mocking framework abilities that you might be used to. Instead you’ll have to do this yourself. Here is a simple example how to test if a method is called.

image

So this was a real short introduction to Moles that I hope helps you come up to speed quickly. The final point that I would like to make is that you can use this on any .Net object even static or sealed objects like DirectoryInfo for instance (try using the code below without Moles):

image

Big thanks to my colleague Marcus Hammarberg for challenging me to write this post!

Enjoy,

Hugo

I don’t want to write comments or run code coverage on autogenerated code

The “warning CS1591: Missing XML comment for publicly visible type or member” issue

You’ve created a WCF service proxy and you’ve XML documentation turned on like the picture shows below.

image

Then you most likely will have a lot of warnings the next time you build your project like so:

image

Don’t despair the solution is close.

Solution

Find the Reference.cs file if you added a Service Reference manually or if you auto generated the Service Reference using the “svcutil.exe” utility open up the generated class.

Add the following line of code in your namespace:

#pragma warning disable 1591 //Disables CS1591 Warning

image

Auto generated code has lousy Code Coverage

Then you’ll be left with the issue that your auto generated code has lousy Code Coverage, if you haven’t written any tests against it that is. The question if you should write tests on auto generated code or not I leave it up to you. I’ll leave at that with the cowardly answer “it depends” Ler The before picture might look like this:

image

Notice how the auto generated namespaces are listed in Code Coverage.

Solution

This is as easily fixed as the XML Warning. In the file where you have the auto generated code use search and replace to add the

[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]

attribute to every class.

image

Finish things off with a Edit->Advanced->Format Document to get a nice formatting and your good to go!

image

Try compiling and watch as your code coverage goes up!

image

Cheers,

Hugo