Ich bin neu in Java-Tests mit JUnit. Ich muss mit Java arbeiten und möchte Unit-Tests verwenden.
Mein Problem ist: Ich habe eine abstrakte Klasse mit einigen abstrakten Methoden. Es gibt jedoch einige Methoden, die nicht abstrakt sind. Wie kann ich diese Klasse mit JUnit testen? Beispielcode (sehr einfach):
abstract class Car {
public Car(int speed, int fuel) {
this.speed = speed;
this.fuel = fuel;
}
private int speed;
private int fuel;
abstract void drive();
public int getSpeed() {
return this.speed;
}
public int getFuel() {
return this.fuel;
}
}
Ich möchte testen getSpeed()
und getFuel()
funktionieren.
Eine ähnliche Frage zu diesem Problem gibt es hier , es wird jedoch kein JUnit verwendet.
Im JUnit-FAQ-Bereich habe ich diesen Link gefunden , aber ich verstehe nicht, was der Autor mit diesem Beispiel sagen möchte. Was bedeutet diese Codezeile?
public abstract Source getSource() ;
java
junit
abstract-class
vasco
quelle
quelle
Antworten:
Wenn Sie keine konkreten Implementierungen der Klasse haben und die Methoden nicht
static
den Sinn haben, sie zu testen? Wenn Sie eine konkrete Klasse haben, testen Sie diese Methoden als Teil der öffentlichen API der konkreten Klasse.Ich weiß, was Sie denken "Ich möchte diese Methoden nicht immer wieder testen, deshalb habe ich die abstrakte Klasse erstellt", aber mein Gegenargument dazu ist, dass der Zweck von Komponententests darin besteht, Entwicklern Änderungen zu ermöglichen. Führen Sie die Tests aus und analysieren Sie die Ergebnisse. Ein Teil dieser Änderungen kann das Überschreiben der Methoden Ihrer abstrakten Klasse umfassen, sowohl
protected
als auchpublic
, was zu grundlegenden Verhaltensänderungen führen kann. Abhängig von der Art dieser Änderungen kann dies Auswirkungen darauf haben, wie Ihre Anwendung auf unerwartete, möglicherweise negative Weise ausgeführt wird. Wenn Sie eine gute Unit-Testing-Suite haben, sollten Probleme, die sich aus diesen Typen ergeben, zum Zeitpunkt der Entwicklung offensichtlich sein.quelle
final
? Ich sehe keinen Grund, dieselbe Methode mehrmals zu testen, wenn sich die Implementierung nicht ändern kannErstellen Sie eine konkrete Klasse, die die abstrakte Klasse erbt, und testen Sie dann die Funktionen, die die konkrete Klasse von der abstrakten Klasse erbt.
quelle
Mit der von Ihnen geposteten Beispielklasse scheint es nicht sinnvoll zu sein,
getFuel()
und zu testengetSpeed()
da sie nur 0 zurückgeben können (es gibt keine Setter).Unter der Annahme, dass dies nur ein vereinfachtes Beispiel zur Veranschaulichung war und Sie berechtigte Gründe haben, Methoden in der abstrakten Basisklasse zu testen (andere haben bereits auf die Auswirkungen hingewiesen), können Sie Ihren Testcode so einrichten, dass ein anonymer Code erstellt wird Unterklasse der Basisklasse, die nur Dummy-Implementierungen (No-Op-Implementierungen) für die abstrakten Methoden bereitstellt.
In Ihrem
TestCase
könnten Sie zum Beispiel Folgendes tun:Testen Sie dann den Rest der Methoden, z.
(Dieses Beispiel basiert auf der JUnit3-Syntax. Für JUnit4 wäre der Code etwas anders, aber die Idee ist dieselbe.)
quelle
Wenn Sie ohnehin eine Lösung benötigen (z. B. weil Sie zu viele Implementierungen der abstrakten Klasse haben und das Testen immer dieselben Prozeduren wiederholen würde), können Sie eine abstrakte Testklasse mit einer abstrakten Factory-Methode erstellen, die durch die Implementierung dieser Methode ausgeführt wird Testklasse. Dieses Beispiel funktioniert oder ich mit TestNG:
Die abstrakte Testklasse von
Car
:Implementierung von
Car
Unit Test Klasse
ElectricCarTest
der KlasseElectricCar
:quelle
Sie könnten so etwas tun
quelle
Ich würde eine innere Klasse von jUnit erstellen, die von der abstrakten Klasse erbt. Dies kann instanziiert werden und Zugriff auf alle in der abstrakten Klasse definierten Methoden haben.
quelle
Sie können eine anonyme Klasse instanziieren und diese Klasse dann testen.
Beachten Sie, dass die Sichtbarkeit
protected
für die EigenschaftmyDependencyService
der abstrakten Klasse gelten mussClassUnderTest
.Sie können diesen Ansatz auch gut mit Mockito kombinieren. Siehe hier .
quelle
Meine Art, dies zu testen, ist in jedem Fall recht einfach
abstractUnitTest.java
. Ich erstelle einfach eine Klasse in der abstractUnitTest.java, die die abstrakte Klasse erweitert. Und testen Sie es so.quelle
Sie können nicht die gesamte abstrakte Klasse testen. In diesem Fall verfügen Sie über abstrakte Methoden. Dies bedeutet, dass diese von einer Klasse implementiert werden sollten, die eine bestimmte abstrakte Klasse erweitert.
In dieser Klasse muss der Programmierer den Quellcode schreiben, der für seine Logik bestimmt ist.
Mit anderen Worten, es macht keinen Sinn, abstrakte Klassen zu testen, da Sie das endgültige Verhalten nicht überprüfen können.
Wenn Sie über wichtige Funktionen verfügen, die sich nicht auf abstrakte Methoden in einer abstrakten Klasse beziehen, erstellen Sie einfach eine andere Klasse, in der die abstrakte Methode eine Ausnahme auslöst.
quelle
Optional können Sie eine abstrakte Testklasse erstellen, die die Logik innerhalb der abstrakten Klasse abdeckt, und diese für jeden Unterklassentest erweitern. Auf diese Weise können Sie sicherstellen, dass diese Logik für jedes Kind separat getestet wird.
quelle