Wednesday, 7 November 2012

Microsoft Fakes Framework


If you have done any Test Driven Development than chances are that you have used one or more mocking frameworks. Mocking frameworks are great in that they isolate your code module from the layers underneath thus allowing you to execute your unit tests without elaborate test set up code. Also, they allow replicating different test scenarios. You can set up different responses from same calls to external components for different test scenarios.

With Visual Studio 2012, Microsoft has introduced a new Mocking framework called Fakes. To date, it is only available with the Ultimate edition of visual studio. The framework is comparable to other open source mocking frameworks such as RhinoMocks and Moq but has the following two advantages over others

  1. Great Integration with Visual Studio: The integration with Fakes with Visual Studio 2012 is brilliant. To create a "fake" of an assembly, a user needs to just right click on the references and click the option "Add Fake Assembly".


  1. Shims: Most mocking framework works by allowing developers to create a "Stub" of an object. Stubs are objects created on the fly, which implements the same interface as the original object. The caller controls the behaviour of the stub by specifying responses for the methods in the interface. Shims are different in that they "inject" code in the original assembly i.e. although the original object will be created but the code executed will the one specified in the shim. This is quite powerful in that it allows developers to specify behaviour of system assemblies, sealed classes and non-virtual methods. E.g. if you are writing some code that need to do something on the 1st day of a year and you are using System.Now, you can "Shim out" this System.Now to return first of January.

When you add a fakes assembly in your test project by right clicking on the reference assembly and clicking the "Add Fakes Assembly" option, visual studio adds the following files

  1. A new "Fakes" folder is created with a .fakes files created in it. For example, if you are creating fakes for "System.Configuration", a file called "System.Configuration.fakes" will be created. 

  1. A new "FakesAssemblies" folder is created with three files created namely originalAssembly.assemblyversion.Fakes.dlloriginalAssembly.assemblyversion.Fakes.xml and originalAssembly.assembly.Fakes.fakesconfig. So, for "System.Configuration" assembly the files generated would be System.Configuration.4.0.0.0.Fakes.dll, System.Configuration.4.0.0.0.Fakes.fakesconfig and System.Configuration.4.0.0.0.fakes.xml.

Visual Studio also adds a reference to the generated assembly in the "FakesAssemblies" folder.

The files in the "Fakes" folder are only generated at the time of adding the fakes assembly. They are added to the solution and should be checked into source control. 

The "FakesAssemblies" folder and all the files in it are generated whenever the project is compiled. This is important because if you are adding fakes for assembly for a changing component, the generation of FakesAssemblies will ensure that all changes are reflected in the generated assembly.

The purpose of this post is not to write details about Fakes and how to use it, but to mention about a "Gotcha" that you might stumble upon while working with it. I spent some time trying to fix that and wanted to write about it so that no one else gets burnt.

The issue was that one of the test projects using fakes was giving a compilation error when built by Team Build and failed with the following error

"Could not resolve this reference. Could not locate the assembly "System.Configuration.4.0.0.0.Fakes". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors."

The error would go away if I added the FakesAssemblies folder to TFS. This is not how it is meant to work. On closer examination, the reason this error happened was because the “Build action” for the .fakes file added to the project was not set correctly. These files should have the build action set to "Fakes". 










It was set to “None” 









and this is the reason why the fakesassemblies were not getting generated in the team build.

14 comments:

Ravi said...

I am using Microsoft Fakes with VS 2013 and using TFS 2010. My local build works fine but the I get the below error with TFS build "The type or namespace name 'Fakes' does not exist in the namespace". The build action is set to "Fakes" for .Fakes files. What am I missing on TFS server?

Hamid said...

Hi Ravi,

Can you confirm that your build server has Visual Studio 2013 or Visual Studio 2012 Ultimate Edition on it. Fakes is not supported in other versions / flavors of Visual Studio.

Ravi said...

Hi Hamid,

Thank you for your reply. Yes, the build server has Visual Studio 2013 Ultimate. Do I have to make any changes to the build definition or the TFS build template to build the Fakes test project?

Hamid said...

No, you don't need any changes in build template.

Are you using MSBuild Platform of "x86"? The Fakes assemblies are resolved by an MSBuild target "ResolveFakesReferences" which reside at

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\Fakes\Microsoft.QualityTools.Testing.Fakes.target.

which makes me think that it only works on the x86 platform.

Ravi said...
This comment has been removed by the author.
Ravi said...

The TFS Build definition builds the solution using C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe with the following switches
/p:Configuration="Release" /p:Platform="Any CPU"

Ravi said...

Hi Hamid,

I modified the defaulttemplate.xaml to use MSBuild.exe v12.0 and the build is working fine. (followed your post http://hamidshahid.blogspot.com/2013/10/building-visual-studio-2013-solutions.html). Now need to try out your other blog to run the Fakes based tests on TFS 2013(http://hamidshahid.blogspot.com/2012/11/unit-tests-using-microsoft-fakes.html)

Thanks for your help. Your Blog is very helpful.

Hamid said...

Oh yea, for Visual Studio 2013, you would need MSBuild 12.0. Sorry, I went down a completely tangent there :)

For future reference, to use x86 version of MSBuild in your team build, set the Build process parameter "MSBuild Platform" to x86.

Unknown said...

Hi Hamid,

I tried all your things to fix my CI build using TeamCity.
But it doesn't work... any bright ideas ?

http://stackoverflow.com/questions/25699114/teamcity-cant-find-the-something-fakes-dll/25719862#25719862

Unknown said...

Thanks! I found your post very useful. I was swearing to TFS for half an hour... ;-)

Hamid said...

Cheers Marino,
Glad that it helped.

Kamal said...

I am having the same issue, checked everything, the build action is set to Fake. Using VS2013 Ultimate, i am not sure what is missinng, it works fine with VS 2013. Not generating on MSBuild. It is using v12.0 MSBuild.exe.

Please let me know if i am missing anything.

Nerissa said...

Thanks, I have done this ...
MEDIAPORTAL | FREE DOWNLOAD

Unknown said...

Hamid - Thanks for helping me out!!!!
I don't know anything about Fakes, but thanks to your post, I understood someone didn't add the FakesAssemblies directory to the project and apparently VS2013 doesn't know to overcome this while VS2012 succeed in handling this

You Rock!!
Michal