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.

28voto

Don Kirkby Punkte 46803

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.

22voto

ema Punkte 5377

Das Testen privater Methoden unterbricht die Kapselung Ihrer Klasse, denn jedes Mal, wenn Sie die interne Implementierung ändern, unterbrechen Sie den Client-Code (in diesem Fall die Tests).

Testen Sie also keine privaten Methoden.

6 Stimmen

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.

1 Stimmen

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.

20voto

simpatico Punkte 10039

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 :)

19voto

Victor Grazi Punkte 14274

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);

19voto

Will Sargent Punkte 4317

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.

4 Stimmen

Als Teil der jmockit-Bibliothek haben Sie Zugriff auf die Klasse Deencapsulation, die das Testen privater Methoden erleichtert: Deencapsulation.invoke(instance, "privateMethod", param1, param2);

0 Stimmen

Ich verwende diesen Ansatz immer wieder. Sehr hilfreich

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