Microsoft Fakes – Customizing the System Whitelist (or, enabling Fakes for classes you’ve always wanted to fake, like WebClient)

Testing
9472

So you’re sitting down planning some tests for your shiny new code, only to find that your code uses WebClient to download a file. No problem – you’ve been reading about Microsoft’s new Fakes framework, so you just right-click the System reference in your test project and select “Create Fakes” and you get a bunch of cool fakes to work with.

But going a bit deeper into the Rabbit Hole, you realize that there are no fakes for System.Net classes. What gives?

The White-List

It turns out that when you right-click a reference and select “Add Fakes” a fakes file is created for that assembly in the Fakes folder. When you add a Fakes lib for System, you in fact get 2 fakes files: one for mscorlib and one for System.

image

Since System is a large library, the Fakes framework doesn’t automatically generate you a fake for every System class. One of the classes that doesn’t have a fake created by default is System.Net.WebClient. In order to force a fake Shim for this class, you’ll need to override the default “white-list” of classes. Fortunately this is relatively straight-forward to do.

The Fakes Config File

Double-click System.fakes to open it in the editor – it’s just an XML file. It does come with an XSD, so as you type in this file IntelliSense will guide you (just like the Force, Luke). Within the tag, add a tag and within that an tag and you’re good to go. Here’s my Fakes file for adding a WebClient fake:








Remember to recompile!


Here’s some example code using the WebClient fake:

public class HttpFunctions
{
public void Download(string url, string fileName)
{
var w = new WebClient();
w.DownloadFile(url, fileName);

}
}

[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestFakeWebClient()
{
using (ShimsContext.Create())
{
ShimWebClient.AllInstances.DownloadFileStringString = (w, url, fileName) =>
{
File.WriteAllText(fileName, url);
};

var c = new HttpFunctions();
string guidFileName = Guid.NewGuid().ToString() + ".html";
c.Download("http://www.bing.com", guidFileName);

Assert.IsTrue(File.Exists(guidFileName));
string contents = File.ReadAllText(guidFileName);
Assert.AreEqual("http://www.bing.com", contents);
File.Delete(guidFileName);
}
}
}

Happy faking!