KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > junit > JUnitExtensions


1 package org.apache.ojb.junit;
2
3 import junit.framework.AssertionFailedError;
4 import junit.framework.TestCase;
5 import junit.framework.TestResult;
6
7 /**
8  * Extensions for junit to write test cases for multithreaded tests.
9  * All classes are from an
10  * <a HREF="http://www.javaworld.com/javaworld/jw-12-2000/jw-1221-junit.html">
11  * javaworld article</a> about junit.
12  *
13  * @author <a HREF="mailto:armin@codeAuLait.de">Armin Waibel</a>
14  * @version $Id: JUnitExtensions.java,v 1.1 2004/04/05 17:11:49 arminw Exp $
15  */

16 public class JUnitExtensions
17 {
18     /**
19      * A multi-threaded JUnit test case.
20      * To perform test cases that spin off threads to do tests: <p>
21      * <UL>
22      * <LI>Extend <code>MultiThreadedTestCase</code>
23      * <LI>Write your tests cases as normal except for when you want to spin off threads.
24      * <LI>When you want to spin off threads:
25      * <UL>
26      * <LI>Instead of implementing <code>Runnable</code> extend <code>MultiThreadedTestCase.TestCaseRunnable</code>.
27      * <LI>Define <code>runTestCase ()</code> to do your test, you may call <code>fail (), assert ()</code> etc. and throw
28      * exceptions with impunity.
29      * <LI>Handle thread interrupts by finishing.
30      * </UL>
31      * <LI>Instantiate all the runnables (one for each thread you wish to spawn) and pass an array of them
32      * to <code>runTestCaseRunnables ()</code>.
33      * </UL>
34      * That's it. An example is below:
35      * <PRE>
36      * public class MTTest extends JUnitExtensions.MultiThreadedTestCase
37      * {
38      * MTTest (String s) { super (s); }
39      * public class CounterThread extends JUnitExtensions.TestCaseRunnable
40      * {
41      * public void runTestCase () throws Throwable
42      * {
43      * for (int i = 0; i < 1000; i++)
44      * {
45      * System.out.println ("Counter Thread: " + Thread.currentThread () + " : " + i);
46      * // Do some testing...
47      * if (Thread.currentThread ().isInterrupted ()) {
48      * return;
49      * }
50      * }
51      * }
52      * }
53      *
54      * public void test1 ()
55      * {
56      * TestCaseRunnable tct [] = new TestCaseRunnable [5];
57      * for (int i = 0; i < 5; i++)
58      * {
59      * tct[i] = new CounterThread ();
60      * }
61      * runTestCaseRunnables (tct);
62      * }
63      * }
64      * </PRE>
65      * <BR><STRONG>Category: Test</STRONG>
66      * <BR><STRONG>Not guaranteed to be thread safe.</STRONG>
67      */

68     public static class MultiThreadedTestCase extends TestCase
69     {
70         /**
71          * The threads that are executing.
72          */

73         private Thread JavaDoc threads[] = null;
74         /**
75          * The tests TestResult.*/

76         private TestResult testResult = null;
77
78         /**
79          * Simple constructor.
80          */

81
82         public MultiThreadedTestCase(String JavaDoc s)
83         {
84             super(s);
85         }
86
87         /**
88          * Interrupt the running threads.
89          */

90         public void interruptThreads()
91         {
92             if (threads != null)
93             {
94                 for (int i = 0; i < threads.length; i++)
95                 {
96                     threads[i].interrupt();
97                 }
98             }
99         }
100
101         /**
102          * Override run so we can squirrel away the test result.*/

103
104         public void run(final TestResult result)
105         {
106             testResult = result;
107             super.run(result);
108             testResult = null;
109         }
110
111         /**
112          * Run the test case threads.*/

113
114         protected void runTestCaseRunnables(final TestCaseRunnable[] runnables)
115         {
116             if (runnables == null)
117             {
118                 throw new IllegalArgumentException JavaDoc("runnables is null");
119             }
120             threads = new Thread JavaDoc[runnables.length];
121             for (int i = 0; i < threads.length; i++)
122             {
123                 threads[i] = new Thread JavaDoc(runnables[i]);
124             }
125             for (int i = 0; i < threads.length; i++)
126             {
127                 threads[i].start();
128             }
129             try
130             {
131                 for (int i = 0; i < threads.length; i++)
132                 {
133                     threads[i].join();
134                 }
135             }
136             catch (InterruptedException JavaDoc ignore)
137             {
138                 System.out.println("Thread join interrupted.");
139             }
140             threads = null;
141         }
142
143         /**
144          * Handle an exception. Since multiple threads won't have their
145          * exceptions caught the threads must manually catch them and call
146          * <code>handleException ()</code>.
147          * @param t Exception to handle.
148          */

149         private void handleException(final Throwable JavaDoc t)
150         {
151             synchronized (testResult)
152             {
153                 if (t instanceof AssertionFailedError)
154                 {
155                     testResult.addFailure(this, (AssertionFailedError) t);
156                 }
157                 else
158                 {
159                     testResult.addError(this, t);
160                 }
161             }
162         }
163
164         // ======================================================================
165
// inner class
166
// ======================================================================
167
/**
168          * A test case thread. Override runTestCase () and define
169          * behaviour of test in there.*/

170         protected abstract class TestCaseRunnable implements Runnable JavaDoc
171         {
172             /**
173              * Override this to define the test*/

174
175             public abstract void runTestCase()
176                     throws Throwable JavaDoc;
177
178             /**
179              * Run the test in an environment where
180              * we can handle the exceptions generated by the test method.*/

181
182             public void run()
183             {
184                 try
185                 {
186                     runTestCase();
187                 }
188                 catch (Throwable JavaDoc t) /* Any other exception we handle and then we interrupt the other threads.*/
189                 {
190                     handleException(t);
191                     interruptThreads();
192                 }
193             }
194         }
195     }
196 }
197
Popular Tags