Meffert IT Consulting

JUnit Profi Tipps


JUnit Profi-Tipps kaufen

Thread - Ressourcen

GroboUtils - JUnit Extension, auch für Thread-Tests

Singletons with needles and thread

Threads testen

Der folgende Text ist eine Ergänzung zu Abschnitt 5.6 Threads testen
aus dem Buch JUnit Profi-Tipps - Software erfolgreich testen

Auf Seite 114 wurde beschrieben, wie der Rückgabewert eines Threads mit Hilfe von Thread.sleep(int) ermittelt werden kann. Die dargestellte Lösung wurde dort wegen ihrer Nebenwirkungen als Antipattern gekennzeichnet. 

Weil die Darstellung in Listing 5.10 unvollständig ist, hier das komplette Listing 5.10 samt der zu testenden Thread-Klasse MyService (fett gedruckt das Original-Listing aus dem Buch):

1  import junit.framework.*;

3  public class MyTest extends TestCase {

  public void testInvoke() throws Exception {
6      int[] numbers = new int[] {1, 2, 3};
7      MyService service = new MyService(numbers);
8      service.invoke();
9      Thread.sleep(1000); // die 1000 bei Bedarf erhöhen!
10     assertEquals("6",service.getStringResult());
11   }
12
13   class MyService {
14     private int[] m_numbers;
15     private boolean finished;
16
17     MyService(int[] numbers) {
18       m_numbers = numbers;
19     }
20
21     public void invoke() {
22       new Thread() {
23         public void run() {
24           int x = 0;
25           while (true) {
26             x++;
27             try {
28               sleep(10);
29             } catch (InterruptedException iex) {}
30             if (x>100) {
31               finished = true;
32               break;
33             }
34           }
35         }
36       }
.start();
37     }
38
39     public String getStringResult() {
40       if (finished) {
41         return "6";
42       }
43       else {
44         return "0";
45       }
46     }
47   }
48 }

Listing 5.10 (erweitert): Rückgabewert eines Threads testen

Die Klasse MyService implementiert keine sinnvolle Funktionalität, sie dient nur zur Veranschaulichung.

Wichtigste Anmerkung zum obigen Listing: Die Zusicherung (siehe Zeile 10) muss im selben Thread wie die JUnit-Testklasse liegen! Eine Zusicherung in Klasse MyService hat keine direkte Auswirkung auf JUnit, lässt also keinen Test scheitern.

Weiterhin: Der Thread in Klasse MyService (ab Zeile 22) muss direkt nach Konstruktion gestartet werden (siehe Zeile 36). Normalerweise schlägt der Test fehl (je nach Systemkonfiguration). Erhöht man die Sleep-Zeit in Zeile 9 von 1000 auf 2000, sollte der Test nicht mehr fehlschlagen.

Wie schon im Buch beschrieben, sollte diese Variante nicht verwendet werden, weil die Zeit, die beim Aufruf von Thread.sleep(...) einzusetzen ist, nicht exakt bestimmt werden kann. Dies führt unweigerlich zu zu langen Wartezeiten, was sich negativ auf die Laufzeit der Tests auswirkt. Je nach Systemkonfiguration (Hardware, Betriebssystem, laufende Prozesse) fällt die minimal benötigte Sleep-Zeit zudem unterschiedlich aus!