Mock-Objekte und Fixtures in C++-Tests: Wie man Code ohne Angst schreibt

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

Einleitung: Warum Tests ohne Mocks und Fixtures eine Lotterie sind

\n\n

Stellen Sie sich vor, Sie schreiben Code für ein Raumschiff. Ihre Funktion berechnet die Flugbahn und greift dabei auf das Motorsteuerungsmodul zu. Wie überprüfen Sie, ob die Flugbahn korrekt ist, ohne den echten Motor zu starten? In der realen Welt wäre das eine Katastrophe. In der Welt von C++ ist das eine Aufgabe für Mock-Objekte und Fixtures.

\n\n

Wenn Sie jemals Unit-Tests in C++ geschrieben haben, sind Sie sicherlich auf Probleme gestoßen: Der Test schlägt aufgrund des Netzwerks, der Datenbank oder des Dateisystems fehl. Oder Sie geben 10 Zeilen für die Datenvorbereitung für jede Überprüfung aus. Kommt Ihnen das bekannt vor? Dann ist dieser Artikel genau das Richtige für Sie.

\n\n

Wir werden untersuchen, wie Mock-Objekte in C++ helfen, Code von der Außenwelt zu isolieren, und wie Fixtures helfen, die Testeinrichtung wiederzuverwenden. Kein überflüssiger Text, nur Code und Praxis. Los geht's!

\n\n

Was sind Mock-Objekte und warum werden sie in C++ benötigt

\n\n

Ein Mock-Objekt (oder einfach Mock) ist ein Ersatz für ein reales Objekt, das dessen Verhalten nachahmt. Sie sagen dem Mock: "Wenn die Methode getData() aufgerufen wird, gib 42 zurück." Und es gibt gehorsam 42 zurück, ohne auf die Datenbank, API oder Datei zuzugreifen.

\n\n

In C++ sind Mocks besonders wichtig, da die Sprache keine Fehler verzeiht. Wenn Ihre Klasse vom Netzwerk abhängt und das Netzwerk ausfällt, wird der Test fehlschlagen, obwohl Ihr Code perfekt ist. Mocks lösen dieses Problem: Sie isolieren den zu testenden Code.

\n\n

Die wichtigsten Anwendungsszenarien für Mock-Objekte in C++:

\n
    \n
  • Externe Dienste (Datenbanken, REST-APIs, Dateien).
  • \n
  • Komplexe Berechnungen, die Tests verlangsamen (Kryptografie, Rendering).
  • \n
  • Nicht-deterministische Funktionen (rand(), time()).
  • \n
  • Überprüfung der Interaktion: Wurde die Methode aufgerufen, wie oft, mit welchen Argumenten.
  • \n
\n\n

Für die Erstellung von Mocks in C++ ist der De-facto-Standard die Bibliothek Google Mock (auch bekannt als gmock), die im Paket mit Google Test enthalten ist. Man kann Mocks aber auch manuell schreiben – für kleinere Projekte ist das sogar einfacher.

\n\n

Fixtures: Die Bühne für den Test bereiten

\n\n

Ein Test Fixture ist eine Sammlung von Objekten und Daten, die für die Ausführung des Tests benötigt werden. Anstatt jedes Mal zu schreiben:

\n\n
MyClass obj;\nobj.init("data");\nobj.connect();
\n\n

…lagern Sie dies in ein Fixture aus. Google Test unterstützt Fixtures durch Vererbung von ::testing::Test. Das ist nicht nur bequem – es ist eine bewährte Praxis für C++-Tests.

\n\n

Fixtures lösen drei Aufgaben:

\n
    \n
  1. Wiederverwendung von Code – einmal eingerichtet, in allen Tests verwendbar.
  2. \n
  3. Sauberkeit der Tests – jeder Test beginnt mit dem gleichen Zustand.
  4. \n
  5. Automatische Bereinigung – wenn Ressourcen freigegeben werden müssen, geschieht dies im Destruktor des Fixtures.
  6. \n
\n\n

Und jetzt verbinden wir Mocks und Fixtures in einem Beispiel.

\n\n

Einen Test mit Mock-Objekt und Fixture schreiben: Ein reales Beispiel

\n\n

Angenommen, wir haben eine Klasse WeatherReporter, die Wetterdaten über eine API abruft. Wir möchten die Methode getTemperature() testen, ohne auf den echten Server zuzugreifen.

\n\n

Schritt 1: Das Interface definieren

\n\n

Um einen Mock einzusetzen, benötigen wir eine abstrakte Klasse. Dies ist der entscheidende Punkt: Mocks arbeiten über Polymorphie.

\n\n
// weather_api.h\nclass WeatherAPI {\npublic:\n    virtual ~WeatherAPI() = default;\n    virtual double getTemperature(const std::string& city) = 0;\n    virtual bool isAvailable() = 0;\n};
\n\n

Schritt 2: Den Mock mit Google Mock implementieren

\n\n
// mock_weather_api.h\n#include <gmock/gmock.h>\n#include "weather_api.h"\n\nclass MockWeatherAPI : public WeatherAPI {\npublic:\n    MOCK_METHOD(double, getTemperature, (const std::string& city), (override));\n    MOCK_METHOD(bool, isAvailable, (), (override                

Blogs

Buchempfehlungen