Mock-Objekte und Fixtures in Java: Wie man schneller und intelligenter testet

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Warum Ihre Java-Tests fehlschlagen (und wie Sie das beheben)

\n\n

Sie haben perfekten Code geschrieben. Der Service funktioniert, die Logik ist einwandfrei und Bugs gibt es nur in fremden Projekten. Aber wenn Sie die Tests ausführen... Da ist ein Verbindungsfehler zur Datenbank, dort antwortet eine externe API nicht, und im dritten Test gibt es einen NullPointerException, weil die Konfiguration nicht richtig geladen wurde. Kommt Ihnen das bekannt vor?

\n\n

Das Problem ist, dass klassische Tests von der externen Umgebung abhängen. Datenbank, REST-Dienste, Dateisystem – all das macht Tests anfällig, langsam und unberechenbar. Die Lösung sind Mock-Objekte und Fixtures. Das sind nicht nur modische Wörter, sondern Werkzeuge, die Chaos in Ordnung verwandeln.

\n\n

In diesem Artikel werden wir anhand realer Beispiele durchgehen, wie man Mock und Fixtures in Java-Tests richtig einsetzt. Sie erfahren, worin der Unterschied zwischen Stub und Mock besteht, wie man Fixtures für komplexe Szenarien konfiguriert und warum Mockito Ihr bester Freund ist. Los geht's!

\n\n

Mock-Objekte: Simulation ohne Schmerz

\n\n

Was ist ein Mock und wozu braucht man ihn?

\n\n

Ein Mock-Objekt ist eine Nachbildung einer realen Komponente, die sich so verhält, wie Sie es vorgeben. Anstatt eine Datenbank hochzufahren oder eine externe API aufzurufen, erstellen Sie einen „Platzhalter", der vorab festgelegte Daten zurückgibt.

\n\n

Stellen Sie sich vor: Sie testen einen Service, der E-Mail-Benachrichtigungen versendet. Für einen echten Test müssten Sie einen Mail-Server hochfahren, SMTP konfigurieren, die Warteschlange prüfen... Mit einem Mock-Objekt überprüfen Sie einfach, ob der Service die Versandmethode mit den richtigen Parametern aufgerufen hat. Schnell, sauber, kontrollierbar.

\n\n

Mock vs Stub: Was ist der Unterschied?

\n\n

Anfänger verwechseln diese Begriffe oft. Lassen Sie uns Klarheit schaffen:

\n\n
    \n
  • Stub – gibt festgelegte Daten zurück. Sie sagen: „Wenn die Methode getUser() aufgerufen wird, gib ein User-Objekt mit dem Namen 'John' zurück." Ein Stub prüft nicht, wie oft er aufgerufen wurde.
  • \n
  • Mock – gibt nicht nur Daten zurück, sondern prüft auch das Verhalten. Sie können sagen: „Stelle sicher, dass die Methode sendEmail() genau einmal mit einer bestimmten Adresse aufgerufen wurde."
  • \n
\n\n

Einfach ausgedrückt: Ein Stub sagt „gib mir Daten", ein Mock sagt „gib mir Daten und prüfe, wie ich verwendet werde". In der Praxis werden meist Mock-Objekte verwendet, da sie mehr Kontrolle bieten.

\n\n

Unser ersten Mock mit Mockito schreiben

\n\n

Mockito ist die beliebteste Bibliothek für Mocks in Java. Sie ist mit JUnit 5 und Spring Boot integrierbar und die Syntax ist so einfach, dass Sie sie in fünf Minuten lernen.

\n\n

Angenommen, Sie haben einen Service OrderService, der von einem Repository OrderRepository abhängt. Anstelle des echten Repositorys erstellen wir einen Mock:

\n\n
import static org.mockito.Mockito.*;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mock;\nimport org.mockito.junit.jupiter.MockitoExtension;\nimport org.junit.jupiter.api.extension.ExtendWith;\n\n@ExtendWith(MockitoExtension.class)\npublic class OrderServiceTest {\n\n    @Mock\n    private OrderRepository orderRepository;\n\n    @Test\n    void testCreateOrder() {\n        // Mock-Objekt erstellen\n        OrderService orderService = new OrderService(orderRepository);\n        \n        // Verhalten des Mocks konfigurieren\n        when(orderRepository.save(any(Order.class)))\n            .thenReturn(new Order(1L, "test@example.com", 100.0));\n        \n        // Die zu testende Methode aufrufen\n        Order result = orderService.createOrder("test@example.com", 100.0);\n        \n        // Ergebnis überprüfen\n        assertThat(result.getId()).isEqualTo(1L);\n        // Überprüfen, dass die Methode save genau einmal aufgerufen wurde\n        verify(orderRepository, times(1)).save(any(Order.class));\n    }\n}
\n\n

In diesem Beispiel haben wir:

\n
    \n
  • Einen Mock für OrderRepository mit der Annotation @Mock erstellt.
  • \n
  • Konfiguriert, dass beim Aufruf von save() eine vorab erstellte Bestellung zurückgegeben werden soll.
  • \n
  • Überprü

Blogs

Buchempfehlungen