使用 Microsoft Fakes 隔離測試中的程式碼

程式碼隔離是一種通常使用 Microsoft Fakes 之類的工具實作的測試策略,其中,您要測試的程式碼會與應用程式的其餘部分隔開。 將與受測程式碼互動的應用程式部分取代為虛設常式或填充碼,即可達成此區隔。 這些是由測試控制的小段程式碼,會模擬被取代之實際部分的行為。

此方法的優點是您可以全心隔離測試程式碼的特定功能。 如果測試失敗,您知道原因出在隔離的程式碼內,而不是其他地方。 此外,使用 Microsoft Fakes 提供的虛設常式和填充碼時,即使應用程式的其他部分尚未運作,您仍可測試程式碼。

需求

注意

對於使用 Microsoft Fakes 的測試,無法使用 Visual Studio 進行分析。

Microsoft Fakes 在程式碼隔離中的角色

Microsoft Fakes 提供了虛設常式和填充碼這兩個機制,在程式碼隔離中扮演重要角色。

  • 虛設常式:虛設常式用來將類別取代為實作相同介面的小型替代項。 為此,您的應用程式必須設計成讓每個元件只相依於介面,而不相依於其他元件。

  • 填充碼:填充碼用來在執行階段修改應用程式已編譯的程式碼。 應用程式不會進行指定的方法呼叫,而是會執行您的測試所提供的填充碼。 填充碼可取代您無法修改的組件 (例如 .NET 組件) 的呼叫。

一般而言,虛設常式會用於 Visual Studio 解決方案中的呼叫,而填充碼則用來呼叫其他參考的組件。 這是因為在您的解決方案中,依虛設常式需要的方式定義介面以分離元件,是很好的做法。 不過,外部組件通常不會隨附個別介面定義,因此會改用填充碼。

Diagram that show Fakes replacing other components.

何時應使用虛設常式的建議

虛設常式通常用於 Visual Studio 解決方案內的呼叫,因為依虛設常式需要的方式定義介面以分離元件,是很好的做法。 不過,外部組件 (例如 System.dll) 通常未隨附個別介面定義,因此在這些情況下會改用填充碼。

使用虛設常式時,必須將應用程式設計為不同元件各自獨立,不會彼此相依,而僅相依於介面定義。 此分離作業能夠強化應用程式並提升其彈性,還能讓您將受測元件連線至介面的虛設常式實作,以進行測試。

實際上,您可以從 Visual Studio 中的介面定義產生虛設常式類型,然後將實際元件取代為測試中的虛設常式。

何時應使用填充碼的建議

虛設常式用於 Visual Studio 解決方案內的呼叫,而填充碼則通常用來呼叫其他參考的組件。 這是因為 System.dll 之類的外部組件通常未隨附個別介面定義,因此必須改用填充碼。

不過,使用填充碼時需考量一些因素:

效能:由於填充碼會在執行階段重寫程式碼,因此執行速度較慢。 虛設常式類型沒有這樣的效能負荷,執行速度與虛擬方法一樣快。

靜態方法、密封類型:您只能使用虛設常式來實作介面。 因此,虛設常式類型不能用於靜態方法、非虛擬方法、密封虛擬方法、密封類型中的方法等等。

內部類型:虛設常式和填充碼都可以與使用組件屬性 InternalsVisibleToAttribute 存取的內部類型搭配使用。

私人方法:如果方法簽章的所有類型都是可見的,則填充碼可以取代私人方法的呼叫。 虛設常式只能取代可見的方法。

介面和抽象方法:虛設常式提供可用於測試的介面和抽象方法實作。 填充碼無法檢測介面和抽象方法,因為它們沒有方法主體。


將 .NET Framework 中的 Microsoft Fakes 轉換為 SDK 樣式專案

將使用 Microsoft Fakes 的 .NET Framework 測試專案轉換為 SDK 樣式的 .NET Framework、.NET Core 或 .NET 5+ 專案。

您只需在 .NET Framework 的 Microsoft Fakes 設定中進行最基本的變更,就能轉換至 .NET Core 或 .NET 5.0。 您須考量的案例如下:

  • 如果您使用自訂專案範本,就必須確定那是 SDK 樣式,而且是針對相容的目標架構建置的。

  • 某些類型在 .NET Framework 和 .NET Core/.NET 5.0 中存在於不同的組件中 (例如,System.DateTime 存在於 .NET Framework 的 System/mscorlib 中,以及 .NET Core 和 .NET 5.0 的 System.Runtime 中),在這些案例中,您必須變更虛設的組件。

  • 如果您有對 Fakes 組件和測試專案的組件參考,您可能會看到關於遺漏參考的建置警告:

    (ResolveAssemblyReferences target) ->
    warning MSB3245: Could not resolve this reference. Could not locate the assembly "AssemblyName.Fakes". Check to make sure the assembly exists on disk.
    If this reference is required by your code, you may get compilation errors.
    

    此警告是產生 Fakes 時所做的必要變更所引起的,可以忽略。 從專案檔中移除組件參考即可避免此警告,因為我們現在會在建置期間隱含地新增這些參考。

執行 Microsoft Fakes 測試

只要 Microsoft Fakes 組件存在於設定的 FakesAssemblies 目錄中 (預設為 $(ProjectDir)FakesAssemblies),您就可以使用 vstest 工作來執行測試。

要使用 vstest 工作對使用 Microsoft Fakes 的 .NET Core 和 .NET 5+ 專案進行分散式測試,需要 Visual Studio 2019 Update 9 Preview 20201020-06 和更新版本。

不同 .NET 和 Visual Studio 版本中的 Microsoft Fakes 相容性和支援

以 .NET Framework (非 SDK 樣式) 為目標的舊版專案中的 Microsoft Fakes。

  • 在 Visual Studio Enterprise 2015 和更新版本中支援產生 Microsoft Fakes 組件。
  • Microsoft Fakes 測試可使用所有可用的 Microsoft.TestPlatform NuGet 套件來執行。
  • 在 Visual Studio Enterprise 2015 和更新版本中,使用 Microsoft Fakes 的測試專案支援程式碼涵蓋範圍。

SDK 樣式 .NET Framework、.NET Core 和 .NET 5.0 或更新版本中的 Microsoft Fakes

  • Microsoft Fakes 組件產生在 Visual Studio Enterprise 2019 Update 6 中是預覽版,在 Update 8 中則預設為啟用。
  • 以 .NET Framework 為目標的專案,可使用所有可用的 Microsoft.TestPlatform NuGet 套件來執行 Microsoft Fakes 測試。
  • 以 .NET Core 和 .NET 5.0 或更新版本為目標的專案,可使用 16.9.0-preview-20210106-01 版和更新版本的 Microsoft.TestPlatform NuGet 套件來執行 Microsoft Fakes 測試。
  • 在 Visual Studio Enterprise 2015 版和更新版本中,以 .NET Framework 為目標、且使用 Microsoft Fakes 的測試專案支援程式碼涵蓋範圍。
  • Visual Studio 2019 Update 9 和更新版本提供以 .NET Core 和 .NET 5.0 或更新版本為目標、且使用 Microsoft Fakes 之測試專案的程式碼涵蓋範圍支援。