3227 Stimmen

Wie teste ich eine Klasse, die private Methoden, Felder oder innere Klassen hat?

Wie kann ich mit JUnit eine Klasse testen, die interne private Methoden, Felder oder verschachtelte Klassen hat?

Es scheint schlecht, den Zugriffsmodifikator für eine Methode zu ändern, nur um einen Test durchführen zu können.

327 Stimmen

Der beste Weg, eine private Methode zu testen, ist, sie nicht direkt zu testen

30 Stimmen

3 Stimmen

Warum sollte eine private Funktion getestet werden? Sie wird ohnehin automatisch getestet (und muss getestet werden), wenn Sie die Funktion/Methode testen, die die private Funktion verwendet.

156voto

John Channing Punkte 6373

Im Allgemeinen ist ein Unit-Test dazu gedacht, die öffentliche Schnittstelle einer Klasse oder Unit zu testen. Daher sind private Methoden Implementierungsdetails, von denen Sie nicht erwarten würden, dass sie explizit getestet werden.

23 Stimmen

Das ist IMO die beste Antwort, oder wie es gewöhnlich heißt: Testen Sie das Verhalten, nicht die Methoden. Unit-Tests sind kein Ersatz für Quellcode-Metriken, statische Code-Analyse-Tools und Code-Reviews. Wenn private Methoden so komplex sind, dass sie separate Tests benötigen, dann müssen sie wahrscheinlich umstrukturiert werden, und nicht mit mehr Tests überhäuft werden.

20 Stimmen

Schreiben Sie also keine privaten Methoden, sondern erstellen Sie einfach 10 weitere kleine Klassen?

5 Stimmen

Nein, es bedeutet im Grunde, dass Sie die Funktionalität der privaten Methoden mit der öffentlichen Methode testen können, die sie aufruft.

80voto

Richard Le Mesurier Punkte 28822

Dies sind nur zwei Beispiele dafür, wo ich eine private Methode testen möchte:

  1. Entschlüsselungsroutinen - Ich würde nicht für jedermann sichtbar machen, nur um sie zu Testzwecken sichtbar machen, sonst kann jeder sie zum Entschlüsseln verwenden. Aber sie sind dem Code inhärent, kompliziert, und müssen immer funktionieren (die offensichtliche Ausnahme ist Reflection, mit der man in den meisten Fällen sogar private Methoden einsehen kann, wenn SecurityManager nicht so konfiguriert ist, dass dies verhindert wird).
  2. Erstellen eines SDK für die Gemeinschaft Konsum. Hier bekommt die Öffentlichkeit eine ganz andere Bedeutung, da es sich Code ist, den die ganze Welt sehen kann sehen kann (nicht nur intern in meiner Anwendung). Ich stelle Code in private Methoden, wenn ich nicht dass die SDK-Benutzer ihn sehen - ich sehe das nicht als Codegeruch an, sondern lediglich wie SDK-Programmierung funktioniert. Aber natürlich muss ich natürlich trotzdem meine privaten Methoden testen, und sie sind es, wo die eigentliche Funktionalität meines SDKs lebt.

Ich verstehe die Idee, nur den "Vertrag" zu testen. Aber ich sehe nicht, dass man dafür plädieren kann, den Code tatsächlich nicht zu testen - je nachdem, wie man es sieht.

Mein Kompromiss besteht also darin, die JUnits mit Reflection zu verkomplizieren, anstatt meine Sicherheit und mein SDK zu gefährden.

10 Stimmen

Sie sollten eine Methode niemals öffentlich machen, nur um sie zu testen, private ist nicht die einzige Alternative. Kein Zugangsmodifikator ist package private und bedeutet, dass Sie einen Unit-Test durchführen können, solange sich Ihr Unit-Test im selben Paket befindet.

0 Stimmen

@ngreen das ist alles wahr, aber darum geht es in der Frage nicht. OP fragt nach dem Testen privater Methoden. Standard ist nicht dasselbe wie privat; wie bereits erwähnt, kann man eine Standardzugriffsmethode einer Klasse leicht erkennen, indem man die Klasse einfach im selben Paket deklariert. Bei privatem Zugriff ist Reflexion erforderlich, was eine ganz andere Sache ist.

2 Stimmen

Ich habe mich zu Ihrer Antwort, insbesondere zu Punkt 1, geäußert, nicht zum OP. Es gibt keinen Grund, eine Methode privat zu machen, nur weil Sie nicht wollen, dass sie öffentlich ist.

68voto

Thomas Owens Punkte 110966

Die privaten Methoden werden von einer öffentlichen Methode aufgerufen, so dass die Eingaben zu Ihren öffentlichen Methoden auch private Methoden testen sollten, die von diesen öffentlichen Methoden aufgerufen werden. Wenn eine öffentliche Methode fehlschlägt, dann könnte das ein Fehler in der privaten Methode sein.

0 Stimmen

Wahre Tatsache. Das Problem ist, wenn die Implementierung komplizierter ist, z. B. wenn eine öffentliche Methode mehrere private Methoden aufruft. Welche davon ist fehlgeschlagen? Oder wenn es sich um eine komplizierte private Methode handelt, die weder offengelegt noch in eine neue Klasse übertragen werden kann.

0 Stimmen

Sie haben bereits erwähnt, warum die private Methode getestet werden sollte. Sie sagten "dann könnte das sein", Sie sind sich also nicht sicher. IMO ist die Frage, ob eine Methode getestet werden sollte, orthogonal zu ihrer Zugriffsebene.

53voto

Mikhail Punkte 2473

In der Spring Framework können Sie private Methoden mit dieser Methode testen:

ReflectionTestUtils.invokeMethod()

Zum Beispiel:

ReflectionTestUtils.invokeMethod(TestClazz, "createTest", "input data");

3 Stimmen

Die sauberste und prägnanteste Lösung bisher, aber nur, wenn Sie Spring verwenden.

48voto

supernova Punkte 2864

Ein anderer Ansatz, den ich verwendet habe, besteht darin, eine private Methode in package private oder protected zu ändern und sie dann mit der @VisibleForTesting Anmerkung der Google Guava-Bibliothek.

Dies zeigt jedem, der diese Methode verwendet, dass er vorsichtig sein muss und nicht direkt darauf zugreifen darf, auch nicht in einem Paket. Auch eine Testklasse muss sich nicht im selben Paket befinden physisch sondern im selben Paket unter dem Namen Test Ordner.

Wenn zum Beispiel eine zu prüfende Methode in src/main/java/mypackage/MyClass.java dann sollte Ihr Testaufruf in src/test/java/mypackage/MyClassTest.java . Auf diese Weise haben Sie Zugriff auf die Testmethode in Ihrer Testklasse.

2 Stimmen

Ich wusste nichts davon, es ist interessant, aber ich denke immer noch, dass man Designprobleme hat, wenn man diese Art von Annottaion braucht.

3 Stimmen

Für mich ist das so, als würde man, anstatt dem Brandschutzbeauftragten einen einmaligen Schlüssel zu geben, um die Brandschutzübung zu testen, die Haustür unverschlossen lassen und ein Schild an der Tür anbringen, auf dem steht: "Unverschlossen für Testzwecke - wenn Sie nicht von unserem Unternehmen sind, bitte nicht eintreten".

0 Stimmen

@FrJeremyKrieg - was bedeutet das?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X