Komponenten- und Integrationstests in Minimal-API-Apps
Hinweis
Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.
Warnung
Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der Supportrichtlinie für .NET und .NET Core. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Wichtig
Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.
Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.
Von Fiyaz Bin Hasan und Rick Anderson
Einführung in Integrationstests
Integrationstests bewerten die Komponenten einer App auf breiterer Ebene als Komponententests. Komponententests werden verwendet, um isolierte Softwarekomponenten wie z. B. einzelne Klassenmethoden zu testen. Integrationstests bestätigen, dass zwei oder mehr App-Komponenten zusammenarbeiten, um ein erwartetes Ergebnis zu erzielen, ggf. auch unter Einbindung aller Komponenten, die für die vollständige Verarbeitung einer Anforderung erforderlich sind.
Diese umfassenderen Tests werden verwendet, um die Infrastruktur und das gesamte Framework der App zu testen, häufig einschließlich der folgenden Komponenten:
- Datenbank
- Dateisystem
- Netzwerk-Appliances
- Anforderung/Antwort-Pipeline
Komponententests verwenden anstelle von Infrastrukturkomponenten künstliche Komponenten, die als Fakes oder Pseudoobjekte bezeichnet werden.
Im Gegensatz zu Komponententests gilt für Integrationstests:
- Sie verwenden die tatsächlichen Komponenten, die von der App in der Produktionsumgebung verwendet werden.
- Sie erfordern mehr Code und Datenverarbeitung.
- Ihre Ausführung dauert länger.
Beschränken Sie daher die Verwendung von Integrationstests auf die wichtigsten Infrastrukturszenarios. Wenn ein Verhalten mithilfe eines Komponententests oder eines Integrationstests getestet werden kann, wählen Sie den Komponententest.
Bei der Besprechung von Integrationstests wird das getestete Projekt häufig als getestetes System oder kurz GS (englisch System Under Test, SUT) bezeichnet. In diesem Artikel wird zum Verweis auf die zu testende ASP.NET Core-Anwendung der Begriff „GS“ verwendet.
Schreiben Sie keine Integrationstests für jede Permutation des Daten- und Dateizugriffs bei Datenbanken und Dateisystemen. Unabhängig davon, wie viele Elemente in einer App mit Datenbanken und Dateisystemen interagieren, ist ein fokussierter Satz von Lese-, Schreib-, Update- und Lösch-Integrationstests üblicherweise in der Lage, die Datenbank- und Dateisystemkomponenten adäquat zu testen. Verwenden Sie Komponententests für Routinetests der Methodenlogik, die mit diesen Komponenten interagieren. Bei Komponententests beschleunigt die Verwendung von Fake- oder Pseudoergebnissen für eine Infrastruktur die Testausführung.
Integrationstests in ASP.NET Core
Integrationstests in ASP.NET Core erfordern Folgendes:
- Es wird ein Testprojekt verwendet, um die Tests einzugrenzen und auszuführen. Das Testprojekt enthält einen Verweis auf das GS.
- Das Testprojekt erstellt einen Testwebhost für das GS und verwendet einen Testserverclient, um Anforderungen und Antworten im Zusammenhang mit dem GS zu verarbeiten.
- Um die Tests auszuführen und die Testergebnisse zu melden, wird ein Test-Runner verwendet.
Integrationstests folgen einer Sequenz von Ereignissen, die die üblichen Testschritte Arrange, Act und Assert umfassen:
- Der Webhost des GS wird konfiguriert.
- Es wird ein Testserverclient erstellt, um Anforderungen an die App zu senden.
- Der Testschritt Arrange wird ausgeführt: Die Test-App bereitet eine Anforderung vor.
- Der Testschritt Act wird ausgeführt: Der Client sendet die Anforderung und empfängt die Antwort.
- Der Testschritt Assert wird ausgeführt: Die tatsächliche Antwort wird je nach der erwarteten Antwort als Pass oder Fail bewertet.
- Der Prozess wird so lange fortgesetzt, bis alle Tests ausgeführt wurden.
- Die Testergebnisse werden gemeldet.
Üblicherweise ist der Testwebhost anders konfiguriert als der normale Webhost der App für die Testläufe. Beispielsweise könnten für die Tests eine andere Datenbank oder andere App-Einstellungen verwendet werden.
Infrastrukturkomponenten wie der Testwebhost und der In-Memory-Testserver (TestServer) werden durch das Paket Microsoft.AspNetCore.Mvc.Testing bereitgestellt oder verwaltet. Durch die Verwendung dieses Pakets werden die Testerstellung und -ausführung optimiert.
Das Microsoft.AspNetCore.Mvc.Testing
-Paket verarbeitet die folgenden Aufgaben:
- Es kopiert die Datei für Abhängigkeiten (
.deps
) aus dem GS in dasbin
Verzeichnis des Testprojekts. - Es legt das Inhaltsstammelement auf das Projektstammelement des GS fest, damit statische Dateien und Seiten/Ansichten bei der Ausführung der Tests gefunden werden.
- Es stellt die Klasse WebApplicationFactory zur Optimierung des Bootstrappings des GS mit
TestServer
bereit.
In der Dokumentation der Komponententests wird beschrieben, wie Sie ein Testprojekt und einen Test-Runner einrichten. Ferner finden Sie dort ausführliche Anweisungen zum Ausführen von Tests sowie Empfehlungen zum Benennen von Tests und Testklassen.
Unterteilen Sie Komponententests und Integrationstests in verschiedene Projekte. Trennen der Tests:
- Damit wird sichergestellt, dass Komponenten für Infrastrukturtests nicht versehentlich in die Komponententests eingeschlossen werden.
- So können Sie steuern, welche Testsätze ausgeführt werden.
Der Beispielcode auf GitHub umfasst ein Beispiel für Komponenten- und Integrationstests bei einer Minimal-API-App.
IResult-Implementierungstypen
Öffentliche IResult-Implementierungstypen im Microsoft.AspNetCore.Http.HttpResults-Namespace können verwendet werden, um Komponententests für minimale Routenhandler auszuführen, wenn anstelle von Lambdafunktionen benannte Methoden verwendet werden.
Im folgenden Code wird die NotFound<TValue>
-Klasse verwendet:
[Fact]
public async Task GetTodoReturnsNotFoundIfNotExists()
{
// Arrange
await using var context = new MockDb().CreateDbContext();
// Act
var result = await TodoEndpointsV1.GetTodo(1, context);
//Assert
Assert.IsType<Results<Ok<Todo>, NotFound>>(result);
var notFoundResult = (NotFound) result.Result;
Assert.NotNull(notFoundResult);
}
Im folgenden Code wird die Ok<TValue>
-Klasse verwendet:
[Fact]
public async Task GetTodoReturnsTodoFromDatabase()
{
// Arrange
await using var context = new MockDb().CreateDbContext();
context.Todos.Add(new Todo
{
Id = 1,
Title = "Test title",
Description = "Test description",
IsDone = false
});
await context.SaveChangesAsync();
// Act
var result = await TodoEndpointsV1.GetTodo(1, context);
//Assert
Assert.IsType<Results<Ok<Todo>, NotFound>>(result);
var okResult = (Ok<Todo>)result.Result;
Assert.NotNull(okResult.Value);
Assert.Equal(1, okResult.Value.Id);
}
Zusätzliche Ressourcen
- Grundlegende Authentifizierungstests sind kein .NET-Repository, sondern wurden von einem Mitglied des .NET-Teams geschrieben. Sie finden darin Beispiele für grundlegende Authentifizierungstests.
- Anzeigen oder Herunterladen von Beispielcode
- Authentifizierung und Autorisierung in Minimal-API-Apps
- Verwenden von Porttunneln in Visual Studio zum Debuggen von Web-APIs
- Testen von Controllerlogik in ASP.NET Core
- RazorKomponententests für Pages in ASP.NET Core