Wie verspotten Sie eine Klasse mit endgültigen Methoden?
-
07-07-2019 - |
Frage
Sagen Sie, ich habe Klasse A mit
class A {
final String foo() {
// .. computing result, contacting database, whatever ..
return "some computed value";
}
// ... and a bazillion other methods, some of them final.
}
Jetzt habe ich Klasse B mit
class B {
String methodIWantToTest(A a) {
String output = a.foo();
// ... whatever this method does, e.g.:
output += "_suffix";
return output;
}
}
Wie würde ich diese Methode testen? Der Grund foo()
Es ist endgültig, weil wir nicht wollen, dass unsere Klassen, die eine Funktionalität ändern. Gleichzeitig, um die Methode wirklich zu testen, möchte ich nicht A.foo()
Methode.
Gibt es eine Möglichkeit, das endgültige Schlüsselwort beispielsweise zu entfernen und eine Annotation in den Zeilen von zu fügen @finalUnlessTest
? Was würdest du empfehlen? Die Umstellung von A an eine Schnittstelle wäre sehr, sehr schwierig, da es eine unserer zentralen Klassen ist und leider ist hübsch extrem gekoppelt.
Bearbeiten #1 Entschuldigung, ich habe vergessen zu erwähnen, wir reden über Java. Wir verwenden noch kein spöttisches Rahmen.
Antworten OK, also: Wow. Jmockit ist einfach unglaublich und ist in meinen Augen die Killer -App zum Testen des Legacy -Code. Besonders in meinem Fall unglaublich nützlich. Vielen Dank! Sie würden im Grunde so etwas wie das Folgende für mein Psuedo-Beispiel tun:
class AMock {
final String foo() {
return "myTestValue";
}
}
class Test extends TestCase {
A mockedA;
B b;
protected void setUp() {
Mockit.redefineMethods( A.class, AMock.class ); // this "pipes" all mocked methods from A to AMock
mockedA = new A(); // NOT new AMock()!!!
b = new B();
}
public void testB() {
assertEquals("myTestValue",mockedA.foo());
assertEquals("myTestValue_suffix",b.methodIWantToTest(mockedA));
}
}
Ist das verdammt cool oder was?
Lösung
Sie können die ausprobieren Jmockit Spottbibliothek.
Andere Tipps
Ich würde das "Finale" entfernen und einfach einen Kommentar eingeben. "Überschreiben Sie diese Methode nicht !!". Wenn Sie Kollegen nicht vertrauen können, dass sie keine einfachen Anweisungen befolgen, ist es trotzdem hoffnungslos.
Mit dem folgenden Code können Sie dies auch tun. Ich sage nicht, dass dies eine gute Praxis ist, aber es ist ein interessanter Gebrauch (Missbrauch?) Von anonymen Klassen.
public class Jobber {
public final String foo() {
return fooFactory() ;
}
String fooFactory() {
return "jobber" ;
}
public static void main(String[] args) {
Jobber jobber = new Jobber() { String fooFactory() { return "prefix " + super.fooFactory() ;} } ;
System.out.println(jobber.foo() );
}
}