Testen mit Mockito ohne Delegation?

dodik4711

Neues Mitglied
Hallo Leute,

ich kämpfe gerade etwas mit Mockito und bräuchte eure Hilfe.
Um das Beispiel etwas verständlicher zu machen erkläre ich den aktuellen Stand in vereinfachter Form.

Ich habe eine Benchmark Klasse deren Aufgabe es ist, einen beliebigen Task zu erledigen.
Die Benchmark Klasse hat einen Konstruktor (der einen Dateipfad erwartet) und eine executeBenchmark() Methode.
Der Konstruktor verarbeitet die empfangene Datei "irgendwie" um nähere Informationen zu dem Task zu gewinnen.
Die executeBenchmark()-Methode instantiiert ein BenchmarkTask Objekt mit den, aus der Datei gewonnenen, informationen und führt den Task danach aus.

Hier ein stark vereinfachter Code.
Java:
public class Benchmark {
    private String taskDescription ;

    public Benchmark(String pathToBenchmarkFile) {
        taskDescription = processBenchmarkFile(pathToBenchmarkFile) ;
    }

    public void executeBenchmark() {
        BenchmarkTask task  = new BenchmarkTask(taskDescription) ;
        task.executeTask();
    }
}

Jetzt würde ich gerne einen Test schreiben, der die executeBenchmark()-Methode ausführt und sicherstellt, dass die executeTask()-Methode 1 mal aufgerufen wurde.

Nun stoße ich aber auf mindestens 2 Probleme.
Normalerweise mockt man ja eine Klasse und delegiert das Objekt weiter um es sozusagen "einzuschleusen".

Also ungefähr so:
Java:
public void shouldCallExecuteTask() {
        BenchmarkTask mockedTask = Mockito.mock(BenchmarkTask.class) ;

        Benchmark benchmark = new Benchmark("someFile.txt") ;
        // hier wird das Objekt delegiert
        benchmark.executeBenchmark(mockedTask);

        Mockito.verify(mockedTask, Mockito.times(1)).executeTask();
}

Die Methode executeBenchmark() erwartet jedoch keine Delegation. Problem Nr. 1!
"Nicht schlimm" dachte ich mir und habe einfach eine eingebaut, womit ich auf das zweite Problem aufmerksam wurde.

Java:
// mit eingebauter Delegation
public void executeBenchmark(BenchmarkTask task) {
        task  = new BenchmarkTask(taskDescription) ;
        task.executeTask();
}

Problem Nr. 2: Auch wenn das gemockte Objekt hierhin delegiert wurde, instantiert die Methode ja trotzdem ein "echtes" BenchmarkTask Objekt.

Kann man in diesem Fall denn überhaupt mocken? Und wenn ja, wie?

Hoffe ich habe es verständlich genug gemacht und bedanke mich im Voraus.
 
G

Gelöschtes Mitglied 6946

Gast
Variante 2 bringt dir gar nichts, da du die übergebene Referenz sofort überschreibst, das dahinterliegende Objekt wird also gar nicht weiter angefasst von deinem Benchmark. Du könntest das Problem damit umgehen, dass du eine Factory für BenchmarkTasks anlegst, die du wiederum an den Benchmark übergibst und diese könntest du in ein Mock packen und wiederum einen Mock von BenchmarkTask herauszugeben. Aber das ist im Grunde übertriebene Komplexität für das, was du machst.

Für mich stellt sich ein wenig die Frage, wo denn ein Ergebnis herauskommt aus deinem Programm. Der Benchmark sollte ein Ergebnis liefern und dieses sollte zurückgegeben werden oder anderweitig zugreifbar sein. Dann könntest du schonmal testen, dass etwas korrektes rauskommt. Darüber hinaus wäre ein Konstruktor, der bereits eine fertige taskDescription bekommt, sehr schön, denn für einen Test erst zwangsläufig aus einer Datei lesen zu müssen, ist vielleicht auch nicht das Wahre (bzw. man könnte es getrennt voneinander testen). Wenn du schließlich eine definierte Eingabe hast und eine prüfbare Ausgabe bekommst, dann ist es auch nicht mehr schlimm, dass du den BenchmarkTask nicht mocken kannst, da das sowieso versteckt ist. Zwar testest du diese Klasse dann implizit mit (was einem Unit-Test etwas wiederspricht), aber ich sehe auf die Schnelle auch keine andere Möglichkeit.
 

dodik4711

Neues Mitglied
Zwar testest du diese Klasse dann implizit mit (was einem Unit-Test etwas wiederspricht)...

Genau das ist mein Dilemma. Ich muss öfters UnitTests für fremde Klassen schreiben, die ich meistens nicht verändern darf/will.
Sobald dort aber eine Methode enthalten ist, die selbstständig ein fremdes Objekt instantiiert, lässt sich kein "sauberer" bzw. "isolierter" UnitTest durchführen, da man dieses fremde Objekt nicht mocken kann.

Etwas naiv habe ich auf einen schönen Zaubertrick gehofft. ^^

Aber trotzdem danke für die Antwort.

Edit:
Habe mir ein paar andere Frameworks fürs mocking angeschaut und PowerMock scheint
Konstruktoren mocken zu können
.
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Testen mit Mockito Allgemeines EE 2
B Spring Testen mit mvc.perform(get(... Allgemeines EE 3
G JavaEE Anwendung Testen Allgemeines EE 0
S Eclipse: Teilmodule beim Testen werden nicht gestartet Allgemeines EE 2
H Webservice testen Allgemeines EE 7
MQue Testen von JEE Projekten Allgemeines EE 3
K Selenium: CSS Testen Allgemeines EE 2
J Mit welchen Tools EJBs testen? Allgemeines EE 12
D Controller-Klassen eines Servlets testen mit JUnit Allgemeines EE 3
P Suche free Webanwendung zu testen Last, Performance Allgemeines EE 3
M Lokales Testen - Pfade unterschiedlich Allgemeines EE 2
P Testen von Struts-Anwendung Allgemeines EE 7
B Tomcat JNDI-Realm - LDAP mit Windows testen? Allgemeines EE 2
OnDemand JSF Seite lädt ohne ende Allgemeines EE 8
OnDemand Deployen ohne .java Files Allgemeines EE 0
A Listen Ausgabe ohne forEach - JSTL Allgemeines EE 5
P Context and Dependency Injection (CDI) ohne Server Allgemeines EE 6
M Initial data ohne SQL imports? Allgemeines EE 6
E Servlet Wie kann ich ohne Hilfe von Eclipse in JBoss mein servlet aufrufen Allgemeines EE 2
LadyMilka Ablaufdiagramm mit/ohne Hibernate Allgemeines EE 2
D Glassfish 3 ohne Cluster Support? Allgemeines EE 1
T Webanwendung ohne Oberfläche Allgemeines EE 5
T Privates Attribut in einer JPA Entitiy Class ohne DB-Spalte? Allgemeines EE 3
B Client starten ohne Eclipse Allgemeines EE 4
V Java-Webservices mit EJB oder ohne? Allgemeines EE 4
B Connection Poll ohne TomCat Allgemeines EE 5
S Downloadbox auch ohne Daten erzwingen // Content-Disposition Allgemeines EE 6
N Warenkorb ohne Datenbank Allgemeines EE 2
J init-Methode eines Servlet ausführen ohne vorherigen request Allgemeines EE 2
S webservice mit tomcat und axis ohne eclipse laufen lassen? Allgemeines EE 2
H Parameterübergabe ohne Formular? Allgemeines EE 7
W deploy-tool ohne GUI? Allgemeines EE 7
TRunKX Werteübergabe von einer *.jsp in eine *.java ohne struts Allgemeines EE 4
B NullPointer ohne message body? Allgemeines EE 3
D JBOSS war aufrufen ohne Projektnamen Allgemeines EE 2
S Kompilieren der JSP-Seiten ohne Aufruf Allgemeines EE 7

Ähnliche Java Themen

Neue Themen


Oben