Frage

Ich schreibe eine Simulation von Bananagrams. Zur Zeit habe ich eine GameMaster Klasse, die die gemeinsame Sammlung von Stücken unterhält. Die deal(Player) Methode befasst sich eine bestimmte Anzahl von Stücken zu diesem Spieler.

Ich möchte für diese Unit-Tests schreiben. Doch an diesem Punkt, ich habe keine Getter und somit keine Möglichkeit, den Status der Objekte zu überprüfen.

Warum nicht noch Getter? Ich will nicht, Code an die öffentliche Schnittstelle hinzufügen nur den Zweck zu testen. Gerade jetzt, es gibt keinen anderen Grund, diese Funktionen verfügbar zu machen.

Was soll ich hier tun? Fügen Sie die Getter wie auch immer, die öffentliche API unübersichtlich (oder in der Hoffnung, dass sie in der Zukunft benötigt werden)? Forgo Unit-Tests? (Klingt wie eine schlechte Idee.)

Oder tut dies darauf hindeuten, dass meine öffentliche Schnittstelle fehlerhaft ist?

War es hilfreich?

Lösung

Statt auf eine konkrete Instanz eines Spielers zu verlassen, schreiben Sie Ihre Unit-Tests an eine Schnittstelle (oder gleichwertiges), und verlassen sich auf Mocks oder andere Interaktion nicht zu bestätigen, dass der Spieler im richtigen Zustand ist, sondern lediglich, dass die korrekte Anrufe (aus der Sicht der Gamemaster-Klasse.

Wenn Sie nicht das korrekte Verhalten der Klasse Gamemaster, ohne sich auf die Validierung der Endzustand des Spielers überprüfen kann, das ein Zeichen ist, dass Ihre Aufgaben fehl am Platz sind. Der Spielleiter sollte sagen, die Spieler was passiert ist, verantwortlich sein, während der Spieler sollte für die Aufnahme der entsprechenden Aktion verantwortlich.

Dies ist auch ein Vorteil, da es bedeutet, dass die Tests für die Gamemaster nur abhängig sein wird, auf das Verhalten der Klasse Gamemaster, und nicht brauchen, berührt werden, wenn der Spieler Klasse sein Verhalten ändert.

Vermeiden Sie das Hinzufügen Getter für Unit-Tests. Wenn Sie gereizt werden, einen Getter hinzuzufügen, schauen, anstatt auf Interaktion Tests anstelle von zustandsbasierten Tests (wie ich gerade beschrieben).

Andere Tipps

Es gibt mehr als ein Mittel, dass ein Stück Code Arbeiten zu überprüfen. Die erste die meisten von uns denken an zustandsbasierten Tests ist (dh unter Verwendung Getter, um zu überprüfen, dass Ihr Objekt der Endzustand ist das, was Sie denken, es sollte). Jedoch ist eine andere Art und Weise der Überprüfung, dass Ihr Code funktioniert, ist das Verhalten oder die Interaktion basierte Tests zu verwenden.

Martin Fowler hat einen anständigen Artikel über den Unterschied hier

Sie sollten die Funktionalität testen, die intern diese Zustandshalte Variablen. Wenn keine öffentliche Funktion wird sie verwenden, dann sind sie tot Code.

Ich würde sagen, dass Ihre Klassen zu viel tun können. Es klingt wie Sie sie speichern Zustand und tun andere Sachen haben.

Überlegen Sie, was sie leichter zu testen würde. Wie würden Sie sie testen, ob Sie den Zustand und die Logik auseinander geteilt? Anstatt nur anrufen

GameMaster gameMaster = new GameMaster;
playerOne.Score = gameMaster.ComputePlayerScore(newScore);

würden Sie den Zustand Nur-Instanz von GameState in den Konstruktor der Gamemaster Routine übergeben:

GameState gameState = new GameState;    
GameMaster gameMaster = new GameMaster(gameState);
playerOne.Score = gameMaster.ComputePlayerScore(newScore);

Dann können Sie Ihr Gerät Prüfroutinen passieren in welcher Daten, die sie benötigen für gameState und newScore, und überprüfen Sie die Ergebnisse in gameState, nachdem es zurückgibt. Dependency Injection ist dein Freund.

Eine Sache, die Sie tun können, ist Unterklasse Ihre Hauptklasse die Getter für die Prüfung zur Verfügung zu stellen. Dies wäre einfacher, wenn Sie Schnittstellen hatte, mit zu arbeiten.

Vererben Getter zu schaffen ist eine halb gefährliche Angelegenheit. Wenn Sie einfach Getter für interne Eigenschaften bietet der Schaden minimal sein, aber Sie müssen vorsichtig sein, dass Sie die Ist testen Klasse und nicht der abgeleiteten Version.

Ich sehe nichts falsch mit Code hinzufügen speziell für Testbarkeit. Unit-Tests sind von unschätzbarem Wert für Regressionstests.

Allerdings ist es auch richtig, dass es nicht Ihre öffentliche API beeinflussen sollte. Daher schlage ich vor machte die Getter Paket-geschützt, und im gleichen Paket wie die Player Klasse Komponententests stellen. (In einer anderen Quelle Ordner obwohl, so dass Sie eine saubere Trennung zwischen Produktionscode und Testcode.)

Unit-Tests Ihren Code machen nicht besser , sie machen Ihre gesamte Anwendung stabiler im Laufe der Zeit mit den Änderungen und zusätzlichen Features. aus diesem Grunde, wenn Sie nicht, dass Sie öffentliche Getter in Ihrer Gamemaster-Klasse nicht haben, müssen sie für Unit-Tests erstellen.

keine Getter bedeutet nicht, Ihre Schnittstelle fließt, Test Driven Development Konzept Schreibmindest Code einen Test zu bestehen (die aus einer Anforderung kommt), wenn Sie nicht tun needem Sie writem nicht. drucken, Spur, Protokoll wird hier lange nach Unit-Tests verschwinden (ok sie sind auch hier zu bleiben, aber in vielen Fällen overated und überstrapazierten)

  

Was soll ich hier tun? Fügen Sie die Getter sowieso, unübersichtlich die öffentliche API (oder in der Hoffnung, dass sie in der Zukunft benötigt werden)?

Ich habe nicht diese Antwort. Wie ist ein Getter „Unordnung“?

Sie tun Test Driven Development. Der Entwurf wird von der absoluten Notwendigkeit, Test alles angetrieben wird.

Getter sind nicht „Unordnung“. Sie sind, wie Sie die Dinge testen.

  

"Forgo Unit-Tests?"

Ich glaube nicht, das ist eine gute Idee.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top