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.

14voto

loknath Punkte 1352

Auf eine private Methode darf nur innerhalb der gleichen Klasse zugegriffen werden. Es gibt also keine Möglichkeit, eine "private" Methode einer Zielklasse von einer beliebigen Testklasse aus zu testen. Ein Ausweg ist die manuelle Durchführung von Einheitstests oder die Änderung der Methode von "privat" in "geschützt".

Und dann kann auf eine geschützte Methode nur innerhalb desselben Pakets zugegriffen werden, in dem die Klasse definiert ist. Wenn Sie also eine geschützte Methode einer Zielklasse testen wollen, müssen Sie Ihre Testklasse im selben Paket wie die Zielklasse definieren.

Wenn die oben genannten Punkte nicht Ihren Anforderungen entsprechen, verwenden Sie der Weg der Reflexion um auf die private Methode zuzugreifen.

0 Stimmen

Sie verwechseln "geschützt" mit "freundlich". Auf eine geschützte Methode kann nur von einer Klasse zugegriffen werden, deren Objekte der Zielklasse zugeordnet werden können (d.h. Unterklassen).

1 Stimmen

Eigentlich gibt es in Java keinen "Friendly", der Begriff lautet "Package" und wird durch das Fehlen des Modifikators "private/public/protected" angezeigt. Ich hätte diese Antwort einfach korrigiert, aber es gibt eine wirklich gute Antwort, die dies bereits sagt - ich würde also empfehlen, sie zu löschen.

0 Stimmen

Ich hätte fast die Bewertung herabgesetzt, weil ich die ganze Zeit dachte: "Diese Antwort ist einfach falsch", bis ich zum letzten Satz kam, der dem Rest der Antwort widerspricht. Der letzte Satz hätte der erste sein müssen.

13voto

Darren Greaves Punkte 3286

Wie bereits von vielen vorgeschlagen, ist es eine gute Möglichkeit, sie über Ihre öffentlichen Schnittstellen zu testen.

Wenn Sie dies tun, ist es eine gute Idee, ein Code Coverage Tool (wie Emma) zu verwenden, um zu sehen, ob Ihre privaten Methoden tatsächlich von Ihren Tests ausgeführt werden.

0 Stimmen

Sie sollten nicht indirekt testen! Nicht nur über die Abdeckung anfassen; testen Sie, dass das erwartete Ergebnis geliefert wird!

13voto

Snicolas Punkte 37333

Heute habe ich eine Java-Bibliothek zum Testen privater Methoden und Felder entwickelt. Sie wurde mit Blick auf Android entwickelt, kann aber wirklich für jedes Java-Projekt verwendet werden.

Wenn Sie einen Code mit privaten Methoden, Feldern oder Konstruktoren haben, können Sie BoundBox . Es tut genau das, wonach Sie suchen. Im Folgenden finden Sie ein Beispiel für einen Test, der auf zwei private Felder einer Android-Aktivität zugreift, um diese zu testen:

@UiThreadTest
public void testCompute() {

    // Given
    boundBoxOfMainActivity = new BoundBoxOfMainActivity(getActivity());

    // When
    boundBoxOfMainActivity.boundBox_getButtonMain().performClick();

    // Then
    assertEquals("42", boundBoxOfMainActivity.boundBox_getTextViewMain().getText());
}

BoundBox macht es einfach, private/geschützte Felder, Methoden und Konstruktoren zu testen. Sie können sogar auf Dinge zugreifen, die durch Vererbung verborgen sind. BoundBox bricht in der Tat die Kapselung auf. Sie ermöglicht Ihnen den Zugriff auf all diese Dinge durch Reflection, BUT alles wird zur Kompilierungszeit geprüft.

Es ist ideal für das Testen von Legacy-Code. Verwenden Sie es vorsichtig ;)

https://github.com/stephanenicolas/boundbox

11voto

Aaron Punkte 3397

Zunächst möchte ich diese Frage stellen: Warum müssen Ihre privaten Mitglieder isoliert getestet werden? Sind sie so komplex und bieten so komplizierte Verhaltensweisen, dass sie unabhängig von der öffentlichen Oberfläche getestet werden müssen? Es handelt sich um Unit-Tests, nicht um "Line-of-Code"-Tests. Kümmern Sie sich nicht um den Kleinkram.

Wenn sie so groß sind, groß genug, dass diese privaten Mitglieder jeweils eine "Einheit" groß in der Komplexität - erwägen Refactoring solche privaten Mitglieder aus dieser Klasse.

Wenn Refactoring unangemessen oder undurchführbar ist, können Sie das Strategiemuster verwenden, um den Zugriff auf diese privaten Mitgliedsfunktionen/Mitgliedsklassen im Rahmen von Unit-Tests zu ersetzen? Im Rahmen von Unit-Tests würde die Strategie eine zusätzliche Validierung bieten, aber in Release-Builds wäre es ein einfaches Pass-Through.

4 Stimmen

Denn oft wird ein bestimmtes Codestück aus einer öffentlichen Methode in eine interne private Methode umgewandelt und ist dann der kritische Teil der Logik, den Sie möglicherweise falsch verstanden haben. Sie möchten dies unabhängig von der öffentlichen Methode testen

1 Stimmen

Selbst der kürzeste Code ist manchmal ohne Unit-Test nicht korrekt. Versuchen Sie einfach, die Differenz zwischen 2 geografischen Winkeln zu berechnen. 4 Zeilen Code, und die meisten werden es nicht beim ersten Versuch richtig machen. Solche Methoden brauchen Unit-Tests, denn sie bilden die Basis für einen vertrauenswürdigen Code. (Und solch nützlicher Code kann auch öffentlich sein; weniger nützlich ist geschützter Code.

9voto

Saša Punkte 3787

Ich möchte Ihnen eine Regel vorstellen, die ich über das Testen habe und die besonders mit diesem Thema zusammenhängt:

Ich denke, dass man niemals Produktionscode anpassen sollte, um um das Schreiben von Tests zu erleichtern.

In anderen Beiträgen werden einige Vorschläge gemacht, wie man die Originalklasse anpassen kann, um eine private Methode zu testen. Wenn Sie die Zugänglichkeit einer Methode/eines Feldes in package private oder protected ändern, nur um sie für Tests zugänglich zu machen, dann vereiteln Sie den Zweck der privaten Zugriffsrichtlinie.

Warum sollten wir überhaupt private Felder/Methoden/Klassen haben, wenn wir eine testgetriebene Entwicklung haben wollen? Sollten wir alles als Paket privat oder sogar öffentlich deklarieren, damit wir ohne Aufwand testen können? - Das glaube ich nicht.

Aus einem anderen Blickwinkel betrachtet. Tests sollten die Leistung und Ausführung der Produktionsanwendung nicht beeinträchtigen. Wenn Sie den Produktionscode ändern, nur um die Tests zu vereinfachen, können Sie die Leistung und die Ausführung der Anwendung in irgendeiner Weise beeinträchtigen. Und wenn man anfängt, den privaten Zugriff auf das Paket private zu ändern, kann man schließlich auf "geniale Ideen" kommen, um der ursprünglichen Klasse weiteren Code hinzuzufügen, der die Lesbarkeit zusätzlich beeinträchtigt und die Leistung der Anwendung beeinträchtigen kann.

Andererseits eröffnen Sie mit der Änderung des privaten Zugriffs in einen weniger restriktiven Zugriff einem Entwickler die Möglichkeit, eine neue Situation bei der künftigen Entwicklung der Anwendung zu missbrauchen. Anstatt ihn zu zwingen, auf die richtige Art und Weise zu entwickeln, eröffnen Sie ihm neue Möglichkeiten und geben ihm die Fähigkeit, in Zukunft falsche Entscheidungen zu treffen.

Natürlich kann es ein paar Ausnahmen von dieser Regel geben, aber man sollte sich darüber im Klaren sein, was die Regel und was die Ausnahme ist und warum sie gemacht wird.

1 Stimmen

Dies ist zwar ein guter Grundsatz, aber ein anderer ist, dass der Code testbar sein sollte. Wenn die Transformation, die der Code durchführen soll, einfach zu verstehen und in kleine Teile zu zerlegen ist (z. B. das Parsen von JSON), sollte das Testen der öffentlichen API ausreichend sein. Wenn der Code mehrere komplizierte Berechnungen durchführt, um das Endergebnis zu erzielen (z. B. ein Kalman-Filter), kann das Testen der einzelnen Schritte des Algorithmus die Prüfung erleichtern. Vor allem das Testen der privaten Methoden kann zeigen, wo das Problem liegt.

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