Unit-Test und Spott
Es scheint eine Menge Fragen zu geben, wann man sich lustig machen soll. Aber ich habe bisher keine Antwort auf meine Frage bekommen. Es kann sein, dass ich keine bestimmte Suchanfrage kenne, die mich auf die Antwort verweisen würde.
Stellen Sie sich vor, wir haben eine Klasse (MyClass). Stellen Sie sich vor, diese Klasse verfügt über Methoden, die sowohl std :: string als auch ein Wrapper-Klassenobjekt (MyStringWrapper in einer anderen Bibliothek definiert) zurückgeben können. MyStringWrapper ist nicht genau ein Aggregator (wir können hier die Verwendung von struct in Betracht ziehen, aber wir bevorzugen eine Klasse für dieses spezielle Beispiel), da sein Setter eine if- und mehrere Kopieroperationen hat. Jetzt gibt es eine 3. Klasse (UserClass), die die Klassen MyClass und MyStringWrapper verwendet.
Als guter SW-Entwickler möchte ich meine UserClass einem Unit-Test unterziehen (viele beziehen sich auf "einen Code riechen"). Für Unit-Tests würde ich gtests und gmock verwenden, um ein Modell der MyClass zu erstellen (nennen wir es MyClassMock). Ich erinnere mich jedoch, dass irgendwo gesagt wurde: "Sie müssen alles verspotten, was in einer anderen Bibliothek / Bibliothek eines Drittanbieters definiert ist." Sowohl std :: string als auch MyStringWrapper sind in Bibliotheken von Drittanbietern definiert.
Nun die Frage. Sollte ich in diesem Fall also Mocks für std :: string und MyStringWrapper erstellen?
Sie können sich die Verwendung des zurückgegebenen std :: string / MyStringWrapper-Objekts als vorstellen
if(myreturnedstdstring.empty())
return 1;
if(mywrapperobject.failed())
return 100;
Ich wurde hier in Kommentaren gefragt. Gibt es einen Grund für Unit-Tests, die alles öffentlich machen und verspotten?
ein anderes Thema erstellen.
Antworten
Alles in std :: ist Teil der Sprache und sollte nicht verspottet werden. Ihr String-Wrapper, der nicht Teil der zu testenden "Einheit" ist, wird möglicherweise verspottet, aber meiner Meinung nach ist ein solcher Wrapper im Allgemeinen so leicht, dass der Mock den Code im Wesentlichen reproduzieren würde. In diesem Fall würde ich mich nicht darüber lustig machen. Wenn sich der Wrapper jedoch in Zukunft ändern könnte, sollten Sie ihn verspotten, wenn Sie einen stabilen Komponententest wünschen. Andererseits wäre ein Testfehler, wenn eine inkompatible Änderung am Wrapper vorgenommen wird, gut, aber schwieriger zu finden, da der Fehler in einer anderen Einheit auftritt.
Ich erinnere mich, dass irgendwo gesagt wurde "Sie müssen alles verspotten, was in einer anderen Bibliothek / Bibliothek eines Drittanbieters definiert ist".
Das war vielleicht einmal der Rat, aber es ist nicht der Rat, der heute allgemein gegeben wird.
Der derzeitige Rat ist, sparsam mit Mock umzugehen, um die folgenden Ziele des Unit-Tests zu erreichen:
- Die Tests können schnell, parallel oder in beliebiger Reihenfolge und jederzeit durchgeführt werden. Dies bedeutet, dass Komponenten, die mit persistentem Speicher (Datenbanken, Dateisysteme), langsamen (Netzwerk-) Verbindungen oder Umgebungsbedingungen interagieren, die Sie nicht einfach kontrollieren können (z. B. Zeit), ein Kandidat für Verspottung sind.
- Alle Pfade durch den zu testenden Code können ausgeübt werden. Wenn eine bestimmte (Fehler-) Antwort von einer Abhängigkeit mit dem realen Code nicht einfach ausgelöst werden kann, könnte dies ein Grund sein, diese Abhängigkeit zu verspotten.
Einfache Datentypen wie Zeichenfolgen, Ihr MyStringWrapper oder sogar Container passen nicht zu diesen Punkten, sodass es keinen Grund gibt, sie zu verspotten.