Webframeworkk/ASP.NET Core/Erweiterter Unit-Test

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

  1. Mock erstellen: var mockRepo = new Mock();
  2. Verhalten festlegen: mockRepo.Setup(r => r.GetAll()).ReturnsAsync(new List());
  3. Mock injizieren: Den Mock an den Konstruktor der zu testenden Klasse übergeben.
  4. 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.

Kategorien: Keine
Zuletzt aktualisiert am 27.02.2026 13:26