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

The easiest way to Install and Boot Windows 8 Developer Preview off a VHD (Virtual Hard Disk)

works-on-my-machine-starburst_3

This post provides the fastest way to get your Windows 8 Developer Preview booting off a VHD. If you’re interested in more details read my previous posts here, here and here.

  1. First of all download Windows 8 Developer Preview here.
  2. Download my script here.
  3. Select Properties on the zip-package and click on the Unblock button.
  4. Extract the zip-package to a folder of your choice.
  5. Mount Windows 8 Developer Preview with your favorite mounting tool, my favorite tool is Virtual Clone Drive you can find it here.
  6. Look for the file “install.wim” in your installation media and remember the path, in my case F:\sources\install.wim.
  7. Open a PowerShell command prompt with the run as Administrator option. You need to run the attached bat-file from a PowerShell console as an Administrator and not from the usual command prompt.
  8. Change directory to the directory where you extracted the zip-package.
  9. Before I show you how to use the CreateBootableVHD.bat file there is 2 important concepts that you need to know:
    • The third parameter in CreateBootableVHD.bat expects you to enter the type of VHD that you want to create. If you choose EXPANDABLE you will need to make sure that you have the specified amount of GB left for the VHD even though the VHD will be small at first.
    • CreateBootableVHD.bat will assign your bootable VHD a drive letter, it’s very important to use a FREE drive letter.
    • When you enter a drive letter make sure you don’t enter a colon after the letter i.e. X and never X:.
  10. Now you’re ready to use the CreateBootableVHD.bat-file like this:
    CreateBootableVHD_v2.bat
    <path where you like to store the VHD, doesn’t work on external drives>
    <size in MB>
    <type FIXED|EXPANDABLE>
    <drive letter assigned to the VHD>
    <path to the wim-file, see number 6 above>

    Ex:
    .\CreateBootableVHD_v2.bat C:\VHD\Win8.vhd 80000 FIXED X F:\sources\install.wim.

Sit back and enjoy as the complete automated process of getting your copy of Windows 8 Developer Preview bootable.

Hope you enjoy it!

Hugo

Creating a bootable VHD the easy way…about Indexes

I’ve seen a lot of people using and downloading my bat-file from my original post here and some of you have even tried some of my more advanced topics here.

There is something worth mentioning with the attached Install-WindowsImage.ps1 that I’ve received feedback from some of you out there. If you would like to install any other Operating System SKU then the default at Index 1 in my bat-file you’ll have to list the images first.

Let’s take a closer look at Install-WindowsImage.ps1:

image

As you can see someone has already been kind enough to provide us with an easy way to list the available images. So if I go ahead and run the example on my own system I get the following:

image

So imagine if I wanted the DataCenter Edition (Full Installation) instead of Standard (Full Installation) I’d have to change the Index in the provided CreateBootableVHD_v2.bat file:

image

Hope that clear any issues with Indexes you might have.

Enjoy!

Hugo