In common C# Unit test, we always meet the problem that our final application is depending on many 3rd party or system references. But for unit test, we need to separate and control the dependency libraries behaviour. One of the solution will be Microsoft Fake
.
Here let me talk about Microsoft Fake , and how to unit test your application which depends on many system or other references.
Microsoft Fake
Microsoft Fakes is a test framework help you isolate the code you are testing by replacing other parts of the application.
Microsoft Fake is highly integrated with Visual Studio and you can easily start to use it with very several clicks.
Fakes come in two flavours:
A
shim
modifies the compiled code of your application at run time so that instead of making a specified method call, it runs the shim code that your test provides. Shims can be used to replace calls to assemblies that you cannot modify, such .NET assemblies.A
stub
replaces a class with a small substitute that implements the same interface. To use stubs, you have to design your application so that each component depends only on interfaces, and not on other components.
A good diagram to distinguish those two:
Comparison | Shim | Stub |
---|---|---|
Performance | Slow ( rewrite code ) | As it is ( just interface implementation ) |
Static method, seal type | ✔ | ✗ |
Internal Type with InternalsVisibleToAttribute | ✔ | ✔ |
Private methods | ✔ if all the types on the method signature are visible | ✗ |
Interfaces and abstract methods | ✗ | ✔ |
Using Shim
Here let we say that we want to test a function in a DemoClassLibrary
.
We have a class that implements something depends on System
library.
1 | using System; |
So this UtcNowTick
is depends on the DateTime
, and right now we want to test this function.
This is a typical scenario for us to use shim
to test because we cannot control the behaviour of the system
library.
First, we add the fake to the library to we want to fake.
After this operation, we can find that we have a fake assembly created:
So right now, we have the fake assembly for system now, and we can control the behaviour of system namespace api as below:
1 | using System; |
As the code show, the fake framework will add an extra code for your faked namespace (such as system
in our demo), and all the extra code will under Fakes
namespace.
We can replace function calls under Fakes
namespace to our test implementation expected. Every type will have a Shim+Typename
under Fakes
for us to replace.
** There is some kinds of different scenarios which we need to test using Shim, here I list some:**
Let’s say that we have a 3rd party library like this:
1 | namespace DemoDependence |
And we have our application that use this library:
1 | using System; |
we start our test.
shim static function
1 | [ ] |
shim instance function
1 | [ ] |
shim constructor
1 | [ ] |
Using Stub
Stum is typically using to implement the interface, let say we have a interface:
1 | public interface IDependenceInterface |
And our Foo has one more function:
1 | public class Foo |
The stub would be like this:
1 | [ ] |
Compile warning issue
When you use fake the System
library, you may see the compilation warning, that is because some type cannot be fakes, you can change the fake configuration file to fixit.
The warning is like below:
Warning 20 Some fakes could not be generated. For complete details, set Diagnostic attribute of the Fakes element in this file to ‘true’ and rebuild the project.
Just shim or stub the things you really need, here is one of my example in real project:
1 | <Fakes xmlns="http://schemas.microsoft.com/fakes/2011/" Diagnostic="true"> |
Other Options
- Moq which is my favourite test framework
References:
- Isolating Code Under Test with Microsoft Fakes
- Using shims to isolate your application from other assemblies for unit testing
- Using stubs to isolate parts of your application from each other for unit testing
And about markdown: