Frage

Ist es besser, Funktionen hinzuzufügen, die den internen Zustand eines Objekts für Unit-Tests zurückgeben, anstatt die Testklasse zu einem Freund zu machen?- insbesondere, wenn die Funktionen außer im Fall von Unit-Tests keinen Nutzen haben.

War es hilfreich?

Lösung

Unit-Tests sollten in 95 % der Fälle nur die öffentlich zugängliche Oberfläche einer Klasse testen.Wenn Sie etwas im Verborgenen testen, dann handelt es sich um das Testen von Implementierungsdetails, was von Natur aus fragil ist, da Sie die Implementierung problemlos ändern können sollten und die Tests trotzdem funktionieren.Es ist nicht nur fragil, sondern Sie könnten auch dazu verleitet werden, Dinge zu testen, die in geplanten Nutzungsszenarien eigentlich nicht möglich sind, was Zeitverschwendung ist.

Wenn der Zweck der Accessoren, die Sie hinzufügen möchten, lediglich darin besteht, zu testen, ob die Funktion den gewünschten Effekt hatte, verstößt Ihr Klassendesign möglicherweise gegen ein anderes Prinzip, nämlich dass eine zustandsautomatenähnliche Klasse immer klar machen sollte, in welchem ​​Zustand sie sich befindet. ob sich das darauf auswirkt, was passiert, wenn Menschen mit der Klasse interagieren.In diesem Fall wäre es richtig, diese schreibgeschützten Zugriffsfunktionen bereitzustellen.Wenn es keine Auswirkungen auf das Verhalten der Klasse hat, lesen Sie noch einmal meinen vorherigen Abschnitt zu den Implementierungsdetails.

Und wie Sie richtig gesagt haben, ist es aus eigenen Gründen auch unerwünscht, die öffentliche Oberfläche einer Klasse mit ungenutzten Dingen zu überladen.

Wenn ich hatte Um in Ihrem Fall zwischen Accessoren und Friending zu wählen, würde ich mich für Friending entscheiden, einfach weil Du Besitzen Sie Ihren Test und können Sie ihn im Notfall ändern.Möglicherweise besitzen Sie den Code des Clowns nicht, der einen Weg findet, Ihre zusätzlichen Accessoren zu verwenden, und dann stecken Sie fest.

Andere Tipps

Ich werde der akzeptierten Antwort nicht einverstanden und stattdessen die Verwendung einer Freundesklasse empfehlen.

Ein Teil des Staates, den Sie testen, ist wahrscheinlich spezifisch für die Implementierung Ihrer Klasse. Sie testen Details, von denen andere Code normalerweise nicht wissen oder sich darum kümmern und sich nicht verlassen sollten. Öffentliche Accessor -Funktionen machen diese Implementierungsdetails Teil der Schnittstelle der Klasse. Wenn der interne Zustand, den Sie testen, nicht Teil der beabsichtigten Schnittstelle ist, sollte er nicht durch öffentliche Funktionen sichtbar sein. Aus puristischer Sicht stecken Sie zwischen zwei falschen Antworten fest, da Freundenklassen auch technisch Teil der öffentlichen Schnittstelle sind. In meinen Augen wird die Frage, welche Option weniger wahrscheinlich zu schlechten Codierungsentscheidungen führt. Mit einer Reihe von implementierungsabhängigen öffentlichen Accessor-Funktionen fördern es versehentlich ein implementierungsabhängiges konzeptionelles Modell der Klasse, was zur implementierungsabhängigen Verwendung der Klasse führt. Es ist weniger wahrscheinlich, dass eine einzelne Freundschaftsklasse, die angemessen benannt und dokumentiert ist, missbraucht wird.

Im Allgemeinen stimme ich der Empfehlung zu, Accessor-Funktionen gegenüber dem direkten Zugriff auf Mitgliedervariablen zu bevorzugen, aber ich bin nicht einverstanden, dass diese bewährte Verfahren für die Einheitsprüfung des implementierungsabhängigen internen Zustands gilt. Ein vernünftiger Mittelweg ist zu verwenden Privatgelände Accessor -Funktionen für diese Zustandsstücke, die Ihr Unit -Test interessiert, und diszipliniert genug, um die Accessor -Funktionen in Ihren Einheitstests zu verwenden. Nur meine Meinung.

Die Verwendung von Freundenklassen für Unit -Tests ist perfekt legitim und ermöglicht es Ihnen, die Kapselung aufrechtzuerhalten. Sie sollten Ihre öffentliche Schnittstelle Ihrer Klassen nicht einfach ändern, um die Klasse nachweisbarer zu machen. Denken Sie so darüber nach. Was ist, wenn Sie eine FTP -Bibliothek von Drittanbietern gekauft haben und versuchen, sie zu verwenden, und die öffentliche Schnittstelle ist mit einer Reihe von Methoden überfüllt, über die Sie nicht einmal aufgrund von Unit -Tests wissen müssen? Selbst das Ändern einer geschützten Schnittstelle, um Unit -Tests zu kompensieren, ist schlecht. Wenn ich von einer Klasse erbt, möchte ich mir keine Sorgen darüber machen müssen, welche Methoden für mich nützlich sind und welche nur aufgrund von Unit -Tests da sind !!! Die Verwendung von Friends -Klassen für Unit -Tests hilft Ihnen dabei, eine einfache, einfacher Verwendung der Klassenschnittstelle beizubehalten. Es hilft, die Kapselung und Abstraktion zu erhalten !!!

Ich habe das Argument gehört, dass die Verwendung von Freunden für Unit -Tests schlecht ist, da die zu testende Klasse nicht mit seiner Testklasse "eng gekoppelt" werden sollte und nichts über seine Testklasse "wissen" sollte. Ich kaufe das nicht. Es ist eine einzige Zeile, die an die Spitze der Klasse hinzugefügt wurde:

Friend Class MyclasStest;

Und jetzt können Sie Ihre Klasse so testen, wie Sie es wollen!

Jetzt stimme ich zu, dass Sie keine Freundesklasse verwenden sollten, es sei denn, dies ist notwendig. Wenn Sie testen können, was getestet werden muss, ohne es zu einem Freund zu machen, tun Sie es auf jeden Fall. Aber wenn das Leben schwierig wird und die Verwendung einer Freundesklasse das Leben wieder einfach macht, verwenden Sie es!

Ich empfehle, Zubehör zu verwenden, anstatt den Zugriff über öffentliche Mitglieder oder Freundenklassen zuzulassen.

Ich glaube nicht, dass die Verwendung von Freundenklassen Ihnen tatsächlich Vorteile bringt, und es hat das Potenzial, Ihr Leben in der Straße viel schlechter zu machen. Wenn Ihr Code lange Zeit bleibt, besteht eine gute Chance, dass er auf eine Weise verwendet wird, die Sie nicht erwarten. Die Zugangsfunktionen könnten jetzt nur zum Testen verwendet werden, aber wer weiß, was in Zukunft passieren wird? Durch die Verwendung von Zubehör, anstatt einen direkten Zugriff auf Variablen zu bieten, erhalten Sie viel mehr Flexibilität, und es hat sehr niedrige Kosten.

Das andere Argument ist, dass es eine gute Gewohnheit ist, Zugangsanwalt und nicht öffentliche Mitglieder zu verwenden. Die Entwicklung guter Gewohnheiten ist eine wichtige Fähigkeit als Programmierer.

Wie wäre es mit dem internen Zustand "geschützt"? Und dann unittest mit der abgeleiteten Klasse.

Ich denke, es muss eine Unterscheidung zwischen der zukunftssicheren Klasse der Klasse geben, indem sie den Benutzern Zubehör zur Verfügung stellen, wenn es sinnvoll ist, dies zu tun, und die Verbesserung der Testbarkeit zu verbessern. Ich bin auch kein großer Fan von Freunden, die sich mit Klassen anfreunden, um zu testen, da dies eine enge Kupplung an einem Ort einführt, an dem ich es vorziehe, sie nicht zu haben.

Wenn die alleinige Verwendung der Zubehör darin besteht, den Testfällen einen Weg zur Überprüfung des internen Zustands der Klasse zu bieten, ist es normalerweise nicht sinnvoll, sie öffentlich aufzudecken. Es kann auch die Implementierungsdetails festigen, die Sie möglicherweise später ändern möchten, aber dann stellen Sie fest, dass Sie es nicht können, weil jemand anderes diese Zubehör verwendet.

Meine bevorzugte Lösung dafür wäre die Bereitstellung geschützt Accessor -Funktionen, um den Nutzern der Klasse klar zu kommunizieren, dass diese nicht Teil der öffentlichen Schnittstelle sind. Ihre Tests würden dann eine minimal abgeleitete Klasse des Originals erstellen, die Call-Through-Stubs für die Funktionen des Elternteils enthält, aber auch die Accessors öffentlich macht, damit Sie sie in den Testfällen verwenden können.

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