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.
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 <Assembly> tag, add a <ShimGeneration> tag and within that an <Add> tag and you’re good to go. Here’s my Fakes file for adding a WebClient fake:
<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
<Assembly Name="System" Version="4.0.0.0"/>
<ShimGeneration>
<Add FullName="System.Net.WebClient"/>
</ShimGeneration>
</Fakes>
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!