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.
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.
Wenn Sie versuchen, vorhandenen Code zu testen, den Sie nur ungern oder gar nicht ändern möchten, ist Reflection eine gute Wahl.
Wenn das Design der Klasse noch flexibel ist und Sie eine komplizierte private Methode haben, die Sie separat testen möchten, schlage ich vor, dass Sie sie in eine separate Klasse auslagern und diese Klasse separat testen. Dabei muss die öffentliche Schnittstelle der ursprünglichen Klasse nicht geändert werden; es kann intern eine Instanz der Hilfsklasse erzeugt und die Hilfsmethode aufgerufen werden.
Wenn Sie schwierige Fehlerbedingungen testen wollen, die von der Hilfsmethode kommen, können Sie einen Schritt weiter gehen. Extrahieren Sie eine Schnittstelle aus der Helferklasse, fügen Sie der Originalklasse einen öffentlichen Getter und Setter hinzu, um die Helferklasse (die über ihre Schnittstelle verwendet wird) zu injizieren, und injizieren Sie dann eine Mock-Version der Helferklasse in die Originalklasse, um zu testen, wie die Originalklasse auf Ausnahmen von der Helferklasse reagiert. Dieser Ansatz ist auch dann hilfreich, wenn Sie die ursprüngliche Klasse testen wollen, ohne auch die Helferklasse zu testen.
Unit test und src code sind ein Paar. Wenn man den src ändert, muss man vielleicht auch den Unit-Test ändern. Das ist der Sinn von Junit-Tests. Sie sollen garantieren, dass alles wie vorher funktioniert. Und es ist in Ordnung, wenn sie kaputt gehen, wenn man den Code ändert.
Ich stimme nicht zu, dass Unit Tests sich ändern sollten, wenn sich der Code ändert. Wenn Sie einer Klasse Funktionalität hinzufügen sollen, ohne die bestehende Funktionalität der Klasse zu ändern, dann sollten die bestehenden Unit-Tests auch nach einer Änderung des Codes bestehen. Wie Peter erwähnt, sollten Unit-Tests die Schnittstelle testen, nicht wie sie intern ausgeführt wird. In der testgetriebenen Entwicklung werden Unit-Tests erstellt, bevor der Code geschrieben wird, um sich auf die Schnittstelle der Klasse zu konzentrieren und nicht darauf, wie sie intern gelöst wird.
Die Antwort von JUnit.org FAQ-Seite :
Aber wenn Sie müssen...
Wenn Sie JDK 1.3 oder höher verwenden, können Sie Reflection verwenden, um den den Zugriffskontrollmechanismus mit Hilfe des PrivilegedAccessor . Für Details zur Verwendung lesen Sie bitte dieser Artikel .
Wenn Sie JDK 1.6 oder höher verwenden und Ihre Tests mit @Test annotieren, können Sie Dp4j um Reflexion in Ihre Testmethoden einzubauen. Für Details zur Verwendung finden Sie unter dieses Testskript .
P.S. Ich bin der Hauptautor von Dp4j , fragen ich wenn Sie Hilfe brauchen :)
PowerMockito ist genau dafür gemacht. Maven-Abhängigkeit verwenden
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>2.0.7</version>
<scope>test</scope>
</dependency>
Dann können Sie
import org.powermock.reflect.Whitebox;
...
MyClass sut = new MyClass();
SomeType rval = Whitebox.invokeMethod(sut, "myPrivateMethod", params, moreParams);
Wenn Sie private Methoden einer Legacy-Anwendung testen wollen, deren Code Sie nicht ändern können, ist eine Option für Java jMockit die es Ihnen ermöglicht, Mocks für ein Objekt zu erstellen, auch wenn sie für die Klasse privat sind.
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.
327 Stimmen
Der beste Weg, eine private Methode zu testen, ist, sie nicht direkt zu testen
30 Stimmen
Lesen Sie den Artikel Testen privater Methoden mit JUnit und SuiteRunner .
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.
7 Stimmen
Ich habe diese Frage in ihren ursprünglichen Zustand zurückversetzt, bevor ich die Frage generiert habe. In ihrem jetzigen Zustand sind die Antworten sehr Java-orientiert, und die Frage konzentrierte sich weitgehend auf das "Wie", was bedeutet, dass die späteren Versionen, die Java auslöschen und für andere Sprachen verallgemeinern, und am Ende den Fokus auf C++ verlagern, viel zu viele der Antworten ungültig machen. Eine verallgemeinerte Form, die nach dem "Wie" in einer beliebigen Sprache und einem beliebigen Framework fragt, würde ebenfalls als viel zu weit gefasst angesehen werden, was bedeutet, dass die letzten Bearbeitungen diese Frage eher in Richtung Schließung als in Richtung Konstruktivität getrieben haben.
8 Stimmen
@AkashVerma: Aus demselben Grund, aus dem Sie Unit-Tests statt nur Systemtests durchführen wollen?
0 Stimmen
Siehe auch: stackoverflow.com/questions/250692/ . Die zugrunde liegende philosophische Frage ist sprachunabhängig.
0 Stimmen
Siehe: github.com/ljr1981/stack_overflow_answers/blob/main/src/ y github.com/ljr1981/stack_overflow_answers/blob/main/testing/
0 Stimmen
Im vorherigen Kommentar zeige ich Ihnen, wie einfach das in Eiffel ist. In diesem Fall habe ich eine Klasse namens SO_34571 mit einem Methoden-Feature namens `my_private_method' erstellt. Beachten Sie, dass auf das Gruppenschlüsselwort "feature" ein {TEST_SET_BRIDGE} folgt. Das bedeutet, dass jede Klasse, die von TEST_SET_BRIDGE erbt (einschließlich ihrer Nachkommen), die Erlaubnis hat, auf jedes Feature der Feature-Gruppe zuzugreifen. Sauber. Einfach. Elegant. Skalierbar. Kontrollierbar. Schön!