使用Microsoft Fakes 進行測試


Microsoft Fakes 可以提供成員模擬的方法.以方便進行單元測試

如果不使用模擬方法我們要關心很多東西,如數據庫的數據變化,接口調用導致的變化,文件、及其它資源的訪問等問題。

使用模擬我們則可以只關系我們需要測試的那部分邏輯。

clip_image001

一 、Stub 和 Shim

Microsoft Fakes 提供了兩種模擬類型成員的方式.以下兩種方式的替代實現,都可以由委托來重新實現.

1.Stub Type,存根類型,可以動態地為接口及非密封的virtual或屬性附加委托,以重新定義其實現,生成的類為強類型.

2.Shim Types,填充類型,解決了密封類或static成員的問題,T的填充類型ShimT可以為T的每個成員提供一個替代實現

二 、選擇原則

由於Stub和Shim的實現方式不同,所以它們也有不同的要求,下面總結了選擇它們的一些原則:

性能方面:運行時使用Shim重寫會影響性能,Stub由於使用的是虛方法,則無此問題

對static方法/sealed類型:Stub類型只可以重寫虛方法,因此,它不適用於static方法/sealed方法/sealed類中的方法,等

Internal類型:對於標記了InternalsVisibleToAttribute的內部類型,Fakes也可以起作用

private方法:如果private方法的簽名上的所有類型都是可見類型,那么可以通過Shim來替換實現.Stub只能替換可見方法.

接口和抽象方法:Stub可以提供接口或抽象方法的替代實現.Shim則不能,因為沒有實際的方法體.

所以建議在一般情況下使用Stub來支持那些可測試性做的非常好的類型,而用Shim來解決那些耦合很大,可測試性很差的代碼或三方組件.

三、如何使用Fakes

假設我們在項目ClassLibrary1中有以下幾個類

   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:          //其它邏輯
  27:          return obj.Read();
  28:      }
  29: }

我們要使用Fakes進行測試只需要在測試項目中引用 ClassLibrary1,並且在之上右鍵->建立 Fakes即可使用Fakes

 

之后我們就可以使用類似以下代碼來模擬一個IDataAccess的實例 ,MyClass.GetMyData  這個static方法的實現

前者即使用Stub,后者即Shim

   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 與其它Mock差不多,只是使用委托來改變方法實現

而Shim則需要建立 ShimsContext的作用域

 

注意:暫時發現Shim測試在Resharper UnitTest Session運行異常,使用VS則無問題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM