Document directory
- I. stub and Shim
- Ii. selection principles
- Iii. How to Use fakes
Microsoft fakes provides member simulation methods to facilitate unit testing.
If you do not use a simulated method, you need to care about a lot of things, such as database data changes, changes caused by interface calls, access to files, and other resources.
Using simulation, we can only link the logic we need to test.
I. stub and Shim
Microsoft fakes provides two types of simulated members. The following two methods can be re-implemented by delegation.
1. StubType. You can dynamically attach Delegation to the interface and non-sealed virtual or attribute to redefine its implementation. The generated class is of a strong type.
2. ShimTypes, fill type, solves the problem of sealing class or static member. The fill type shmms of T can provide an alternative implementation for each member of T.
Ii. selection principles
Because stub and Shim have different implementation methods, they also have different requirements. The following summarizes some principles for choosing them:
Performance: Using Shim rewriting during runtime will affect performance. Stub does not have this problem because it uses virtual methods.
Static Method/sealed type: The stub type can only override virtual methods. Therefore, it is not applicable to methods in the static method, sealed method, sealed class, and so on.
Internal type: Fakes can also be used for internal types marked with internalsvisibletoattribute.
Private Method: If all types in the private method signature are visible, you can use Shim to replace it. stub can only replace the visible method.
Interfaces and abstract methods: Stub can provide an alternative implementation of an interface or abstract method. Shim cannot, because there is no actual method body.
Therefore, it is recommended to use stub in general to support the very good types that can be tested, and use Shim to solve the code or third-party components that are very coupled and poorly tested.
Iii. How to Use fakes
Suppose we are in the projectClasslibrary1There are the following classes
1: public interface IDataAccess
2: {
3: int Read();
4: }
5:
6: public class MyDataAccess : IDataAccess
7: {
8: public int Read()
9: {
10: return Tools.GetNum();
11: }
12: }
13:
14: public class Tools
15: {
16: static public int GetNum()
17: {
18: return 1;
19: }
20: }
21:
22: public class MyClass
23: {
24: public static int GetMyData(IDataAccess obj)
25: {
26: // other logic
27: return obj.Read();
28: }
29: }
To use fakes for testing, you only need to reference it in the test project.Classlibrary1, and right-click on top-> Create fakesYou can use fakes.
Then we can use the following code to simulate an idataaccess instance. The implementation of the static method myclass. getmydata
Stub is used, and shim is used.
1: [TestClass]
2: public class UnitTest1
3: {
4: [TestMethod]
5: public void StubTest()
6: {
7: IDataAccess stockFeed = new ClassLibrary1.Fakes.StubIDataAccess()
8: {
9: Read = () => { return 2; }
10: };
11: Assert.AreEqual(2, MyClass.GetMyData(stockFeed));
12:
13: }
14: [TestMethod]
15: public void ShimTest()
16: {
17: using (ShimsContext.Create())
18: {
19: ClassLibrary1.Fakes.ShimMyClass.GetMyDataIDataAccess = (inc) => { return 2; };
20: Assert.AreEqual(2, MyClass.GetMyData(null));
21: }
22:
23: }
24:
25: }
Stub is similar to other mock, but uses delegation to change the method implementation.
Shim needs to establish the shimscontext scope.
Note: a shim test running exception in resharper unittest session is found temporarily, and no problem occurs when vs is used.