Reputation: 41
I have a problem in trying to reference the mscorlib fake DLL from separate projects, as described below.
I have numerous VS12 solutions for which I'm writing unit tests using MS Fakes. Based on a suggestion in the following URL, I've decided to make a project just for my fake Dlls: Code generation, compilation, and naming conventions in Microsoft Fakes. The idea is that the location of the fake DLLs will be localized and I don't need to have numerous faked DLLs strewn throughout my test projects. (I'll call this the common fakes library.)
In my current unit tests, I'm using shims from PresentationCore
, System.Management
and System
. However, the System shims I'm using are actually in mscorlib.dll
, more specifically Convert (a static class) and DriveInfo (a sealed class). Because I only need these two classes from mscorlib (for now) I've created the following .fakes file for mscorlib:
<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
<Assembly Name="mscorlib" Version="4.0.0.0"/>
<StubGeneration>
<Clear/>
</StubGeneration>
<ShimGeneration>
<Clear/>
<Add FullName="Convert"/>
<Add FullName="DriveInfo"/>
</ShimGeneration>
</Fakes>
For PresentationCore and SystemManagement, I have similar .fakes files that clear and then add classes by name.
However, in my test project, when I add a reference for the mscorlib.4.0.0.0.Fakes DLL from my common fakes library, the tests using the Convert and DriveInfo shims don't run. Instead, the test method throws a Microsoft.QualityTools.Testing.Fakes.Shims.ShimNotSupportedException, naming the unsupported shimmed class. The tests using functionality from PresentationCore and System.Management still work when referencing the common fakes library.
However, if I add a Fakes assembly for System directly (and mscorlib indirectly) in my test project, create the exact same mscorlib.fakes file in my test project, and add references to the local mscorlib.4.0.0.0.Fakes Dll, the tests that threw exceptions when linked to the common fakes library run without a glitch.
I've looked at the mscorlib faked DLL in the common fakes library using Object Browser and compared it to the one built locally and they appear to be the same.
Does anyone have any idea why referencing the mscorlib fake in the common fakes library doesn't work?
Upvotes: 4
Views: 5011
Reputation: 78
It seems that multiple projects with the same fakes assembly can overwrite each other and cause issues. See answer by SteveInCO at https://social.msdn.microsoft.com/Forums/vstudio/en-US/8b4dfe6c-4373-4b9c-bfec-23459d674315/build-fails-on-running-tests-with-shims?forum=vsmantest, and also Microsoft.Win32.ShimRegistryKey not working on build machine, which references the msdn article mentioned in this question, where it points out that creating a separate project with common fakes can optimize the build time.
I think the reason why the fakes file is not working is because the FullName values do not have the full namespaces. Try
<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
<Assembly Name="mscorlib" Version="4.0.0.0"/>
<StubGeneration>
<Clear/>
</StubGeneration>
<ShimGeneration>
<Clear/>
<Add FullName="System.Convert"/>
<Add FullName="System.IO.DriveInfo"/>
</ShimGeneration>
</Fakes>
Upvotes: 0
Reputation: 1312
The thing about Fakes is that it's meant to regenerate the dlls on every build. This is less important for the system dlls, but worth remembering. You should probably keep them within the project, because you can't be sure how the linking between them goes for shims.
I don't know how shims are implemented, but they clearly override methods at runtime. I think we'd need a developer to answer it in more detail, but it could even be an issue with mscorlib, which already has somewhat flaky support for Fakes (by design).
Ultimately though, your goal seems to be to save a couple clicks on your test projects, while risking your fakes losing sync. The chances of it happening aren't important - its probably not worth making your tests less explicit.
The goal of tests is to reduce maintenance costs, so hiding things is less important for them than it would be for your normal code; it just adds steps to the maintenance process. Fakes is arcane enough for most people without the added strain of 'oh, but it's being referenced indirectly... Does that even work?'
Upvotes: 1