Unittest - Objekte simulieren

White_Fox

Top Contributor
Mahlzeit

Ich muß jetzt jede Menge Tests schreiben für Klassen schreiben, die die Daten meines Programms bearbeiten. Und für diese Tests muß ich die Daten logischerweise erst erzeugen. Das ist relativ viel Arbeit - ein ernsthafter Grund, sich mal mit einigen Testwerkzeugen zu befassen.

Ich habe hier Mockito und JUnit, aber ein Problem: Ich hab keine Ahnung wie mir Mockito das Leben leichter machen kann und aus den Tutorials, die ich bisher gelesen habe, werde ich nicht schlau.

Beispiel: Ich hab eine Klasse, diese enthält u.a. eine ArrayList mit lauter Objekten, die z.B. einen Namen haben. Ein Testling soll jetzt von einem bestimmten Objekt den Namen ändern.
Hat irgendjemand eine Idee, wie ich Mockito jetzt diese Objekte nachahmen lassen kann, vielleicht auch ein paar kurze Hinweise wie Mockito das macht?
 
Da sehe ich jetzt keinen Sinn drin Mockito zu verwenden. Du kannst die Liste ja einfach selber initialisieren.

für Mockito sehe ich zum Beispiel dann einen Einsatzzweck, wenn meine Klasse eine Abhängigkeit auf einen komplexeren Service hat, welcher eine List zurückgibt.

Beispielhaft:
Java:
List<Foo> myList = new ArrayList<>();
myList.add(new Foo());
MyService service = mock(MyService.class);
when(service.getList()).thenReturn(myList);
 
Nun, ich wollte das Beispiel etwas einfacher halten-in dem, was ich nachher machen will, ist für die Testvorbereitung schon etwas mehr zu tun als nur eine Liste vorzubefüllen.
Die Klasse, auf der sich die Testlinge austoben sollen, hat mehrere verschiedene Instanzvariablen wenigstens drei verschiedener Klassen, diese haben ihrerseits Instanzvariablen verschiedener Klassen...so geht das bis etwa vier Ebenen runter.

Wenn ich dein Beispiel aber richtig verstehe, dann muß ich mich sowieso darum kümmern wie myList aussehen soll und z.B. die ganze Initialisierung von Foo durchlaufen. Oder Foo ebenfalls von Mockito nachäffen lassen...?
 
Du willst ja auch noch etwas testen. Mockito initialisiert dir keine Daten, sondern bietet lediglich die Möglichkeit das "Gerüst" einer Klasse zu haben und einzelne Methoden zu ersetzen.

Wenn du also eine Referenz auf einen Service hat, der einen Webservice aufruft hast, kannst du diese Methode mocken. Wenn du alles mockst, testest du am Ende nur noch das Mocking-Framework.

Wo möglich würde ich immer auf die tatsächlichen Klassen zurückgreifen. Meiner Meinung nach ist Mockito dann wirklich sinnvoll, wenn das gar nicht geht.
 
Beim Testen hast du mehrere Möglichkeiten. Das erste ist der Dummy. Einfach eine ziemlich leere Klasse, die genau festgelegte Daten zurückgibt. In deinem Fall würde so ein Dummy einen Konstruktior haben, der jedoch nichts macht und bei "GetAll()", eine vorgefertigte Liste zurückgeben. Was du nicht zum Testen brauchst, brauchst du auch nicht zu implementieren. Du müsstest ja wissen, wie deine Daten aussehen, wenn du sie in den Klassen implementiert hast. Du kannst da einen einfachen Datenbaum aufbauen ohne Datenbankzugriff oder anderes. Prinzipiell ist es ja sowieso so, dass du die Daten in mehreren Tests benutzt, oder die Bereitstellung der Daten auch veränderst, um zu testen.
 
Es gibt ein paar Libs, die Daten generieren können, zB https://github.com/j-easy/easy-random oder https://github.com/Devskiller/jfairy.

Besser ist's aber, davor immer noch mal nachzudenken, wie man das mit besserem Design anders lösen könnte. Wenn vier "Ebenen" relevant sind, ist das u.U. ein Zeichen für schlechte Kapselung, und etwas anders umgesetzt bräuchte man nur eine Ebene (kommt natürlich immer auf den Einzelfall an).

Wenn man außerdem Libs nutzt, die Daten mit Zufall generieren, verliert man u.U. Reproduzierbarkeit, dass kann manchmal zu einem Problem werden.
Oftmals bietet sich da als Alternative Builder-/Factory-Pattern an, durchaus auch extra für Tests passend umgesetzt, damit lassen sich passende Daten auch recht flott erzeugen.

Daten generieren würde ich persönlich nur noch in Ausnahmefällen, z.B. wenn man mal eine Liste von 100 Usern mit XY braucht.
 
Hm...ich hab vorhin entdeckt daß ich schonmal Methoden geschrieben habe, um Testobjekte zu generieren. Ich denke, ich werde es dann erstmal dabei belassen.

Danke für die Anregungen/Hinweise/Inspirationen.
 

Zurück
Oben