使用 Microsoft Fakes 在測試期間隔離程式碼
Microsoft Fakes 幫助您找出您透過取代應用程式的其他部分測試與 Stub 或 填充碼的程式碼。這是受測試的控制項小程式碼部分。藉由隔離測試的程式碼,您知道,如果測試失敗,原因 (而非其他地方。Stub 和填充碼也可讓您測試程式碼,即使您的應用程式的其他部分無法運作。
Fakes 分為兩個功能:
Stub 會實作相同介面的小型替代取代類別。若要使用 Stub,您必須設計應用程式,讓每個元件只取決於介面,而其他元件。(由「元件為我們表示以及通常會和更新類別的類別或群組包含組件中)。
Shim 修改應用程式編譯的程式碼在執行階段,以便而不是呼叫指定的方法呼叫,並執行您的測試提供的 Shim 程式碼。Shim 可以用來取代呼叫您無法修改的組件,這樣的 .NET 組件。
需求
- Visual Studio Ultimate
在 Stub 和 Shim 型別之間做選擇。
通常,,因為您同時,開發並更新這些類別應考量的 Visual Studio 專案是元件。您應該考慮使用 Stub 和填充碼呼叫的專案對其他專案在方案中,或是專案參考的其他組件。
為一般方針,在您的 Visual Studio 方案中使用 Stub 和填充碼呼叫到其他參考的組件。這是因為,在您的方案內是很好的作法藉由定義介面分隔元件就像 Stub 要求的。但是,外部組件 (例如 System.dll 通常不提供不同的介面定義,因此,您必須使用填充碼。
其他考量如下:
效能因為它們重寫程式碼在執行階段,填充碼執行速度變慢。Stub 沒有這個效能負荷且相同快速地是,與虛擬方法可以是。
靜態方法,密封型別。 您只能使用 Stub 實作介面。因此,Stub 型別不能是靜態方法,非虛擬方法,密封虛擬方法,在密封型別所採用的方法,依此類推。
**內部型別。**Stub 和 Shim 可以搭配使存取使用組件屬性 InternalsVisibleToAttribute的內部型別。
私用方法如果方法簽章的所有型別都是可見的, Shim 可以取代呼叫私用方法。Stub 只能取代可見的方法。
介面和抽象方法。 Stub 提供可用來測試介面和抽象方法的實作。因為它們沒有方法主體, Shim 無法檢測介面和抽象方法。
一般而言,我們建議您使用將 Stub 型別與您的程式碼基底內的相依性所隔離。 您可以藉由隱藏在介面之後的元件這麼做。Shim 型別可以與不提供可測試的 API 的協力廠商元件隔離。
開始使用 Stub
插入介面
若要使用 Stub,您必須將您要測試的程式碼,在此情況下不明確提到在應用程式中其他元件的類別。由「元件為我們表示類別或類別一起開發並更新和在 Visual Studio 專案通常包含了。應該宣告變數和參數使用介面使用 Factory,因此,應該將或建立其他元件執行個體。例如,如果 StockFeed,是在應用程式的另一個元件的類別,然後就會視為不當的:
return (new StockFeed()).GetSharePrice("COOO"); // Bad
相反地,請定義可由另一個元件實作,因此,可以由 Stub 負責進行測試所實作的介面:
public int GetContosoPrice(IStockFeed feed) { return feed.GetSharePrice("COOO"); }
Public Function GetContosoPrice(feed As IStockFeed) As Integer Return feed.GetSharePrice("COOO") End Function
將 Fakes 組件。
在方案總管中,展開測試專案的參考清單。如果您在 Visual Basic 中工作,您必須選取 [顯示所有檔案] 才能看到參考目錄。
選取要介面之組件的參考 (例如 IStockFeed) 定義。此參考捷徑功能表上,選擇 [將 Fakes 組件。]。
重建方案。
在您的測試,請建構執行個體 Stub 並為其方法的程式碼:
[TestClass] class TestStockAnalyzer { [TestMethod] public void TestContosoStockPrice() { // Arrange: // Create the fake stockFeed: IStockFeed stockFeed = new StockAnalysis.Fakes.StubIStockFeed() // Generated by Fakes. { // Define each method: // Name is original name + parameter types: GetSharePriceString = (company) => { return 1234; } }; // In the completed application, stockFeed would be a real one: var componentUnderTest = new StockAnalyzer(stockFeed); // Act: int actualValue = componentUnderTest.GetContosoPrice(); // Assert: Assert.AreEqual(1234, actualValue); } ... }
<TestClass()> _ Class TestStockAnalyzer <TestMethod()> _ Public Sub TestContosoStockPrice() ' Arrange: ' Create the fake stockFeed: Dim stockFeed As New StockAnalysis.Fakes.StubIStockFeed With stockFeed .GetSharePriceString = Function(company) Return 1234 End Function End With ' In the completed application, stockFeed would be a real one: Dim componentUnderTest As New StockAnalyzer(stockFeed) ' Act: Dim actualValue As Integer = componentUnderTest.GetContosoPrice ' Assert: Assert.AreEqual(1234, actualValue) End Sub End Class
這裡投影片特殊片段是類別 StubIStockFeed。對於受參考組件中的每一個介面, Microsoft 偽造機制產生 Stub 類別。Stub 類別的名稱是衍生自介面的名稱,與「Fakes.Stub」做為前置詞和參數型別的名稱。
Stub 也會產生屬性的 getter 和 setter,為事件和為泛型方法。如需詳細資訊,請參閱使用虛設常式隔離應用程式的各個組件,方便進行單元測試。
開始使用 Shim
假設您的元件包含呼叫 DateTime.Now:
// Code under test:
public int GetTheCurrentYear()
{
return DateTime.Now.Year;
}
在測試期間,,因為虛擬版本方便地傳回不同的值在每次呼叫時,您要填入 Now 屬性。
若要使用 Shim,您不需要修改應用程式程式碼或覆寫其特定方式。
將 Fakes 組件。
在方案總管中,開啟您的單元測試專案的參考並選取要隨方法要偽造的組件的參考。在此範例中, DateTime 類別在 System.dll。若要查看 Visual Basic 參考的專案,選擇 [顯示所有檔案]。
選取 [加入 Fakes 組件。]。
插入填充碼在 ShimsContext
[TestClass] public class TestClass1 { [TestMethod] public void TestCurrentYear() { int fixedYear = 2000; // Shims can be used only in a ShimsContext: using (ShimsContext.Create()) { // Arrange: // Shim DateTime.Now to return a fixed date: System.Fakes.ShimDateTime.NowGet = () => { return new DateTime(fixedYear, 1, 1); }; // Instantiate the component under test: var componentUnderTest = new MyComponent(); // Act: int year = componentUnderTest.GetTheCurrentYear(); // Assert: // This will always be true if the component is working: Assert.AreEqual(fixedYear, year); } } }
<TestClass()> _ Public Class TestClass1 <TestMethod()> _ Public Sub TestCurrentYear() Using s = Microsoft.QualityTools.Testing.Fakes.ShimsContext.Create() Dim fixedYear As Integer = 2000 ' Arrange: ' Detour DateTime.Now to return a fixed date: System.Fakes.ShimDateTime.NowGet = _ Function() As DateTime Return New DateTime(fixedYear, 1, 1) End Function ' Instantiate the component under test: Dim componentUnderTest = New MyComponent() ' Act: Dim year As Integer = componentUnderTest.GetTheCurrentYear ' Assert: ' This will always be true if the component is working: Assert.AreEqual(fixedYear, year) End Using End Sub End Class
Shim 類別名稱傳遞給對原始型別名稱的 Fakes.Shim 組成。參數名稱附加至方法名稱。
上述範例為靜態方法使用一個填充碼。為執行個體方法要使用填充碼,撰寫在型別名稱和方法名稱之間的 AllInstances :
System.IO.Fakes.ShimFile.AllInstances.ReadToEnd = ...
您也可以建立 Shim 特定執行個體的,建構函式的和屬性的。如需詳細資訊,請參閱使用填充碼將應用程式與其他組件隔離,方便進行單元測試。