Ein Beispiel


... [ Seminar "JUnit" ] ... [ Inhaltsverzeichnis ] ... [ zurück ] ... [ weiter ] ...

Übersicht: Ein Beispiel


Klasse Money

Nachdem wir einige der Grundprinzipien von JUnit besprochen haben, möchten wir nun anhand eines kleinen Beispiels die Funktionalität verdeutlichen. Wir werden im weiteren Verlauf eine Klasse erstellen, die folgende Kriterien erfüllen soll:
An dieser Stelle rufen wir uns noch einmal das Grundprinzip von JUnit zur Erinnerung: Erst testen (!), dann Programmcode verfassen. Demnach machen wir uns erst Gedanken darüber, welche Anforderungen an die Klasse Money zu stellen sind und bilden daraus einen simplen Testfall. Die Anforderung könnte in diesem Fall z.B. wie folgt aussehen:
Der entsprechende Testfall würde in Javacode wie folgt aussehen:

01 public class MoneyTest extends TestCase {
02   public void testSimpleAdd() {
03     Money m12EUR = new Money(12, "EUR");
04     Money m14EUR = new Money(14, "EUR");
05 
06     Money expected = new Money(26, "EUR");
07     Money result = m12EUR.add(m14.EUR);
08 
09     Assert.assertTrue(expected.equals(result));
10   }
11 
12   // dient zur Identifikation
13   public MoneyTest(String name) {
14     super(name);
15   }
16 }
code7.java

Codebeispiel 7


In den ersten beiden Zeilen unserer kleinen Testroutine testSimpleAdd haben wir zwei Geldbeträge instanziiert. Weiterhin haben wir in den nächsten beiden Zeilen das Ergebnis auf zwei verschiedene Arten beschrieben: erstens als den Betrag von 26 EUR, zweitens als die Addition der beiden Beträge oberhalb.

Die eigentliche Behauptung wurde erst in der letzten Zeile des Tests aufgeführt: wir gehen davon aus, dass der Test auf Gleichheit wahr ist.

Ausgehend von dieser Testroutine können wir nun die Klasse Money verfassen:

01 public class Money {
02   private double amount;
03   private String currency;
04 
05   public Money(double amount, String currency) {
06     this.amount = amount;
07     this.currency = currency;
08   }
09 
10   public double getAmount() { return this.amount; }
11   public String getCurrency() { return this.currency; }
12 
13   public Money add(Money oMoney) {
14     return new Money(this.amount + oMoney.getAmount(), this.currency);
15   }
16 }
code8.java

Codebeispiel 8


Da die obere Testroutine die equals-Methode unserer Money-Klasse aufrufen wird, müssen wir die von Object geerbte Variante von equals überschreiben. Ein Test auf gleiche Referenzen würde in diesem Fall keinen Sinn machen. Wie sollen jedoch die Anforderungen an diese Methode in der Klasse Money aussehen? Hierbei sind wir wieder bei dem oben erwähnten Grundprinzip. Definieren wir also:

Das an die equals-Methode übergebene Objekt
Die sich aus diesen Behauptungen ergebende Testroutine würde wie folgt aussehen:

01 public void testEquals() {
02   Money m12EUR = new Money(12, "EUR");
03   Money m14EUR = new Money(14, "EUR");
04 
05   Assert.assertTrue(!m12EUR.equals(null));
06   Assert.assertEquals(m12EUR, m12EUR);
07   Assert.assertEquals(m12EUR, new Money(12, "EUR"));
08   Assert.assertTrue(!m12EUR.equals(m14EUR));
09 }
code9.java

Codebeispiel 9


[ nach oben ]

Fixtures

Wie zu erkennen ist findet schon in diesem kleinem Testbeispiel Codeverdopplung statt: die Instanzen m12EUR und m14EUR wurden in beiden Testfällen deklariert. JUnit bietet uns hierzu eine weitere Hilfe an: die sogenannten Fixtures.

Fixtures definieren dabei Objekte, die in mehreren Tests verwendet werden können. Sie werden vor jedem Testlauf durch den Aufruf der Methode setUp() initialisiert. Dadurch können wir davon ausgehen, dass jeder Testfall mit genau den Ausgangswerten arbeitet, wie von uns vorgesehen. Unsere Tests der Klasse Money ergeben sich nach der Erweiterung um Fixtures zu:

01 import junit.framework.*;
02 
03 public class MoneyTest extends TestCase {
04   private Money f12EUR;
05   private Money f14EUR;
06 
07   protected void setUp() {
08     this.f12EUR = new Money(12, "EUR");
09     this.f14EUR = new Money(14, "EUR");
10   } 
11     
12   public void testSimpleAdd() {
13     Money expected = new Money(26, "EUR");
14     Money result = this.f12EUR.add(this.f14EUR);
15       
16     Assert.assertTrue(expected.equals(result));
17   } 
18 
19   public void testEquals() {
20     Assert.assertTrue(!this.f12EUR.equals(null));
21     Assert.assertEquals(this.f12EUR, this.f12EUR);
22     Assert.assertEquals(this.f12EUR, new Money(12, "EUR"));
23     Assert.assertTrue(!this.f12EUR.equals(this.f14EUR));
24   }
25 }
code10.java

Codebeispiel 10


Ausgehend vom Test auf Gleichheit kann nun auch Money.equals implementiert werden:

01 public boolean equals(Object aObject) {
02   if(aObject instanceof Money) {
03     Money aMoney = (Money) aObject;
04 		
05     return aMoney.getCurrency().equals(this.currency) &&
06            aMoney.getAmount() == this.amount;
07   }
08   
09   return false;
10 }
code11.java

Codebeispiel 11


Wir sind hier nun an einem Punkt angelangt, an dem die ersten beiden Tests erfolgreich ausgeführt werden können. Die Testumgebung kann dabei entweder textbasierend oder als Swinganwendung aufgerufen werden. Wir erweitern dazu unsere Testklasse um die folgende Funktion:

01 public class MoneyTest extends TestCase {
02   // ...
03   
04   public static void main(String[] args) {
05     junit.swingui.TestRunner.run(MoneyTest.class);
06     //junit.textui.TestRunner.run(MoneyTest.class);
07   }
08 }
code12.java

Codebeispiel 12


Unterhalb folgt ein Screenshot des erfolgreichen Testverlaufs.





... [ Seminar "JUnit" ] ... [ Inhaltsverzeichnis ] ... [ zurück ] ... [ weiter ] ... [ nach oben ] ...

valid html4 logo Code generated with AusarbeitungGenerator Version 1.1, weblink