Isolieren von getestetem Code mithilfe von Microsoft Fakes

Codeisolation ist eine Teststrategie, die häufig mit Tools wie Microsoft Fakes implementiert wird, wobei der zu testende Code vom Rest der Anwendung getrennt wird. Diese Trennung wird erreicht, indem Teile der Anwendung, die mit dem zu testenden Code interagieren, durch Stubs oder Shims ersetzt werden. Dabei handelt es sich um kleine Codeabschnitte, die von Ihren Tests gesteuert werden und das Verhalten der tatsächlichen Komponenten simulieren, die sie ersetzen.

Der Vorteil dieses Ansatzes besteht darin, dass Sie sich darauf konzentrieren können, die spezifische Funktionalität des Codes isoliert zu testen. Wenn ein Test fehlschlägt, wissen Sie, dass die Ursache im isolierten Code und nicht an einer anderen Stelle liegt. Darüber hinaus können Sie durch die Verwendung von Stubs und Shims, die von Microsoft Fakes bereitgestellt werden, Ihren Code testen, auch wenn andere Teile Ihrer Anwendung noch nicht funktionieren.

Anforderungen

  • Visual Studio Enterprise
  • Ein .NET Framework-Projekt
  • Die Unterstützung von .NET Core, .NET 5.0 (oder höher) und Projekten im SDK-Format ist in Visual Studio 2019 Update 6 als Vorschaufeature enthalten und in Update 8 standardmäßig aktiviert. Weitere Informationen finden Sie unter Microsoft Fakes für .NET Core- und SDK-Projekte.

Hinweis

Die Profilerstellung mit Visual Studio ist nicht für Tests verfügbar, die Microsoft Fakes verwenden.

Die Rolle von Microsoft Fakes bei Codeisolation

Microsoft Fakes spielt eine Schlüsselrolle bei der Codeisolation, indem zwei Mechanismen bereitgestellt werden: Stubs und Shims.

  • Stubs: Diese werden verwendet, um eine Klasse durch etwas Ersatzcode zu ersetzen, der die gleiche Schnittstelle implementiert. Dies setzt voraus, dass Ihre Anwendung so konzipiert ist, dass jede Komponente nur von Schnittstellen und nicht von anderen Komponenten abhängt.

  • Shims: Diese werden verwendet, um den kompilierten Code Ihrer Anwendung zur Laufzeit zu ändern. Anstatt einen bestimmten Methodenaufruf auszuführen, führt Ihre Anwendung den Shimcode aus, den Ihr Test zur Verfügung stellt. Mit Shims können Sie Aufrufe von Assemblys ersetzen, die nicht geändert werden können, etwa .NET-Assemblys.

In der Regel werden Stubs für Aufrufe in der Visual Studio-Projektmappe verwendet und Shims für Aufrufe von anderen Assemblys, auf die verwiesen wird. Dies liegt daran, dass es in Ihrer Projektmappe ratsam ist, die Komponenten zu entkoppeln, indem Schnittstellen so definiert werden, wie es für Stubbing erforderlich ist. Externe Assemblys verfügen jedoch häufig nicht über separate Schnittstellendefinitionen, sodass stattdessen Shims verwendet werden.

Diagram that show Fakes replacing other components.

Empfehlungen zur Verwendung von Stubs

Stubs werden in der Regel für Aufrufe innerhalb Ihrer Visual Studio-Lösung verwendet, da es sich empfiehlt, die Komponenten zu entkoppeln, indem Schnittstellen so definiert werden, wie es für Stubbing erforderlich ist. Externe Assemblys wie „System.dll“ hingegen werden in der Regel nicht mit separaten Schnittstellendefinitionen bereitgestellt, sodass in diesen Fällen stattdessen Shims verwendet würden.

Damit Stubs verwendet werden können, muss die Anwendung so entwickelt werden, dass die verschiedenen Komponenten nicht voneinander, sondern nur von Schnittstellendefinitionen abhängen. Diese Entkopplung macht Ihre Anwendung robuster und flexibler und ermöglicht auch die Herstellung einer Verbindung für Testzwecke zwischen den zu testenden Komponenten und den Stubimplementierungen der Schnittstellen.

In der Praxis können Sie Stubtypen aus den Schnittstellendefinitionen in Visual Studio generieren und dann die reale Komponente in Ihrem Test durch den Stub ersetzen.

Empfehlungen zur Verwendung von Shims

Während Stubs für Aufrufe in Ihrer Visual Studio-Projektmappe verwendet werden, werden Shims in der Regel für Aufrufe von anderen Assemblys verwendet, auf die verwiesen wird. Dies liegt daran, dass externe Assemblys wie „System.dll“ normalerweise nicht mit separaten Schnittstellendefinitionen bereitgestellt werden, daher müssen stattdessen Shims verwendet werden.

Es gibt jedoch einige Faktoren, die bei der Verwendung von Shims zu berücksichtigen sind:

Leistung: Shims werden langsamer ausgeführt, weil der Code zur Laufzeit neu geschrieben wird. Die Leistung von Stubs wird nicht durch diesen Mehraufwand beeinträchtigt. Sie sind so schnell, wie es bei virtuellen Methoden möglich ist.

Statische Methoden, versiegelte Typen: Sie können nur Stubs verwenden, um Schnittstellen zu implementieren. Daher können Stubtypen für folgende Methoden nicht verwendet werden: statische Methoden, nicht virtuelle Methoden, versiegelte virtuelle Methoden, Methoden in versiegelten Typen usw.

Interne Typen: Stubs und Shims können mit internen Typen verwendet werden, die verfügbar gemacht werden, indem das Assemblyattribut InternalsVisibleToAttribute verwendet wird.

Private Methoden: Shims können Aufrufe von privaten Methoden ersetzen, wenn alle Typen in der Methodensignatur sichtbar sind. Stubs können nur sichtbare Methoden ersetzen.

Schnittstellen und abstrakte Methoden: Stubs stellen Implementierungen von Schnittstellen und abstrakten Methoden bereit, die in Tests verwendet werden können. Shims können Schnittstellen und abstrakte Methoden nicht instrumentieren, da sie über keine Methodentexte verfügen.


Übergang von Microsoft Fakes in .NET Framework zu Projekten im SDK-Stil

Umstellen Ihrer .NET Framework-Testprojekte mit Microsoft Fakes auf .NET Framework-, .NET Core- oder .NET 5-Projekte im SDK-Stil.

Für eine Umstellung auf .NET Core oder .NET 5.0 sind minimale Änderungen in Ihrem .NET Framework-Setup für Microsoft Fakes erforderlich. Folgende Fälle müssen berücksichtigt werden:

  • Wenn Sie eine benutzerdefinierte Projektvorlage verwenden, müssen Sie sicherstellen, dass diese im SDK-Format vorliegt und in ein kompatibles Zielframework kompiliert wird.

  • Bestimmte Typen sind in verschiedenen Assemblys in .NET Framework, .NET Core und .NET 5.0 vorhanden (beispielsweise wird System.DateTime in System/mscorlib in .NET Framework und in System.Runtime in .NET Core und .NET 5.0 verwendet). In einem solchen Fall müssen Sie die Assembly für Fakes ändern.

  • Wenn ein Assemblyverweis auf eine Fakes-Assembly und das Testprojekt vorhanden ist, wird möglicherweise eine der folgenden ähnliche Warnung zu einem fehlenden Verweis angezeigt:

    (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.
    

    Diese Warnung ist auf erforderliche Änderungen an der Fakes-Generierung zurückzuführen und kann ignoriert werden. Die Meldung kann durch das Entfernen des Assemblyverweises aus der Projektdatei vermieden werden, weil Verweise jetzt während des Builds implizit hinzugefügt werden.

Ausführen von Microsoft Fakes-Tests

Solange Microsoft Fakes-Assemblys im konfigurierten Verzeichnis FakesAssemblies vorhanden sind (standardmäßig $(ProjectDir)FakesAssemblies), können Sie Tests unter Verwendung der vstest-Aufgabe ausführen.

Für verteilte Tests mit dem vstest-Task für .NET Core- und .NET 5-Projekte mit Microsoft Fakes wird Visual Studio 2019 Update 9 Preview 20201020-06 oder höher benötigt.

Kompatibilität und Unterstützung für Microsoft Fakes in verschiedenen .NET- und Visual Studio-Versionen

Microsoft Fakes in älteren Projekten mit .NET Framework als Ziel (kein SDK-Format)

  • Das Generieren von Microsoft Fakes-Assemblys wird in Visual Studio Enterprise 2015 und höher unterstützt.
  • Microsoft Fakes-Tests können mit allen verfügbaren Microsoft.TestPlatform-NuGet-Paketen ausgeführt werden.
  • Code Coverage wird für Testprojekte mit Verwendung von Microsoft Fakes in Visual Studio Enterprise 2015 und höher unterstützt.

Microsoft Fakes in Projekten für .NET Framework, .NET Core und .NET 5.0 (oder höher) im SDK-Format

  • Das Generieren von Microsoft Fakes-Assemblys ist in Visual Studio Enterprise 2019 Update 6 als Vorschaufeature enthalten und in Update 8 standardmäßig aktiviert.
  • Microsoft Fakes-Tests für Projekte mit .NET Framework als Ziel können mit allen verfügbaren Microsoft.TestPlatform-NuGet-Paketen ausgeführt werden.
  • Microsoft Fakes-Tests für Projekte mit .NET Core oder .NET 5.0 (oder höher) als Ziel können mit Microsoft.TestPlatform-NuGet-Paketen ab der Version 16.9.0-preview-20210106-01 ausgeführt werden.
  • Code Coverage wird für .NET Framework-Testprojekte mit Verwendung von Microsoft Fakes in Visual Studio Enterprise 2015 und höher unterstützt.
  • Code Coverage wird bei Testprojekten für .NET Core oder .NET 5.0 (oder höher) mit Microsoft Fakes ab Visual Studio 2019 Update 9 unterstützt.