Webframeworkk/ASP.NET Core/Erweiterter Unit-Test
Hinweis: Diese Inhalte wurden mit Unterstützung von Künstlicher Intelligenz erstellt und redaktionell überprüft (Transparenzhinweis gemäß Art. 50 EU AI Act).
Dieses Tutorial bietet einen umfassenden Überblick über moderne Tools und Techniken für Unit- und Integrationstests in der .NET-Entwicklung. Wir konzentrieren uns auf Fluent Assertions, AutoFixture, Mocking mit Moq und Integrationstests.
1. Fluent Assertions
Fluent Assertions ist eine Bibliothek, die Unit-Tests durch eine natürlichere, flüssige Syntax lesbarer macht.
Vorteile
- Lesbarkeit: Tests lesen sich wie normales Englisch.
- Wartbarkeit: Klare Fehlermeldungen erleichtern die Fehlersuche.
- Umfangreiches API: Deckt Collections, Strings, Exceptions und mehr ab.
Beispiele
// Einfache Assertions
result.Should().Be(5);
result.Should().NotBeNull();
// String Assertions
name.Should().StartWith("John").And.EndWith("Doe");
// Collection Assertions
list.Should().HaveCount(3).And.Contain("apple");
// Exception Assertions
Action act = () => someMethod();
act.Should().Throw<ArgumentException>().WithMessage("Invalid operation");
2. AutoFixture
AutoFixture automatisiert die Erstellung von Testdaten, was besonders bei komplexen Objekten mit vielen Abhängigkeiten wertvoll ist.
Integration mit xUnit
Installieren Sie das Paket AutoFixture.Xunit2 und nutzen Sie das [AutoData] Attribut:
[Theory, AutoData]
public void CreatePerson_ValidPerson_ReturnsOk(Person person, Mock<IPersonsService> mockPersonsService)
{
// AutoFixture erstellt automatisch eine Instanz von Person
// ... Testlogik
}
Vorteile
- Reduzierung von Boilerplate-Code.
- Einfache Anpassung generierter Daten.
- Fokus auf die eigentliche Testlogik statt auf Daten-Setup.
3. Mocking mit Moq
Mocking ermöglicht es, eine Code-Einheit (Unit) isoliert von ihren Abhängigkeiten (z.B. Datenbanken oder APIs) zu testen.
Funktionsweise
- Mock erstellen:
var mockRepo = new Mock<IPersonsRepository>(); - Verhalten festlegen:
mockRepo.Setup(r => r.GetAll()).ReturnsAsync(new List<Person>()); - Mock injizieren: Den Mock an den Konstruktor der zu testenden Klasse übergeben.
- Interaktionen verifizieren:
mockRepo.Verify(r => r.GetAll(), Times.Once());
Best Practices beim Mocking
- Bedarfsorientiert: Nur das mocken, was für den Test notwendig ist.
- Verhalten statt Details: Testen Sie, was passiert, nicht wie es implementiert ist.
4. Integrationstests
Integrationstests prüfen das Zusammenspiel verschiedener Komponenten (Controller, Services, Datenbank).
Key Elements
- WebApplicationFactory: Simuliert den Webserver im Test.
- HttpClient: Sendet HTTP-Requests an den Testserver.
- In-Memory Database: Ermöglicht schnelle Datenbanktests ohne externe Abhängigkeiten.
Beispiel: CustomWebApplicationFactory
public class CustomWebApplicationFactory : WebApplicationFactory<Program>
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseEnvironment("Test");
builder.ConfigureServices(services => {
// DB-Kontext durch In-Memory Datenbank ersetzen
services.AddDbContext<ApplicationDbContext>(options => {
options.UseInMemoryDatabase("TestDb");
});
});
}
}
5. Best Practices für Unit Tests
Um effektive Tests zu schreiben, sollten diese folgende Kriterien erfüllen:
- Isoliert: Keine Abhängigkeit von Dateisystem oder echten Datenbanken.
- Schnell: Ausführung in wenigen Millisekunden.
- Wiederholbar: Gleiches Ergebnis bei jedem Durchlauf.
- Eindeutig: Nur eine Methode pro Testfall prüfen.
Interview-Tipps
- Erklären Sie den Unterschied zwischen Fakes (Dummy-Implementierung) und Mocks (vordefinierte Rückgabewerte).
- Kennen Sie die Vorteile von
[Theory]gegenüber[Fact]in xUnit. - Betonen Sie die Wichtigkeit der Test-Isolierung.
Hinweis: Diese Inhalte wurden mit Unterstützung von Künstlicher Intelligenz erstellt und redaktionell überprüft (Transparenzhinweis gemäß Art. 50 EU AI Act).