View Javadoc

1   package com.diasparsoftware.util.junit;
2   
3   import java.lang.reflect.*;
4   import java.util.*;
5   
6   import junit.framework.*;
7   
8   import org.apache.commons.collections.*;
9   
10  /***
11   * Create a parameterized test suite from a collection of fixture
12   * objects. Each fixture object is an instance of the test case for
13   * which you wish to provide external fixture data. Use "fixturable"
14   * test case classes: a test case class with an additional constructor
15   * capable of accepting as parameters all the fixture data the test
16   * needs.
17   * 
18   * To use a parameterized test suite, follow these instructions.
19   * <ol>
20   * <li>Add a constructor to accept your fixture data.</li>
21   * <li>Implement <code>setFixture()</code>.</li>
22   * <li>Override <code>getName()</code> to include the name
23   * of your fixture.</li>
24   * </ol> 
25   * 
26   */
27  public class ParameterizedTestSuite extends TestSuite {
28      /***
29  	 * Creates a test suite of fixtured test cases from the specified
30  	 * fixtures.
31  	 * 
32  	 * Each fixtures must be an instance of "fixturable" <code>TestCase</code>.
33  	 * A test case class is fixturable if it defines the method <code>setFixture()</code>
34  	 * taking as a parameter an instance of itself.
35  	 * 
36  	 * @param fixtures
37  	 */
38      public ParameterizedTestSuite(Collection fixtures) {
39  
40          CollectionUtils.forAllDo(fixtures, new Closure() {
41              public void execute(Object input) {
42                  TestCase fixture = (TestCase) input;
43                  addFixturedTests(fixture);
44              }
45          });
46      }
47  
48      private void addFixturedTests(TestCase fixture) {
49          TestSuite unfixturedSuite = new TestSuite(fixture.getClass());
50  
51          Enumeration enumeration = unfixturedSuite.tests();
52          while (enumeration.hasMoreElements()) {
53              TestCase eachTestCase =
54                  (TestCase) enumeration.nextElement();
55  
56              addFixtureToTestCase(fixture, eachTestCase);
57              addTest(eachTestCase);
58          }
59      }
60  
61      private void addFixtureToTestCase(
62          TestCase fixture,
63          TestCase eachTestCase) {
64  
65          Class fixtureClass = fixture.getClass();
66          try {
67              Method setFixtureMethod =
68                  fixtureClass.getMethod(
69                      "setFixture",
70                      new Class[] { fixtureClass });
71  
72              setFixtureMethod.invoke(
73                  eachTestCase,
74                  new Object[] { fixture });
75          }
76          catch (SecurityException e) {
77              addTest(
78                  warning(
79                      "Unable to invoke setFixture() in class "
80                          + fixtureClass.getName()));
81          }
82          catch (NoSuchMethodException e) {
83              addTest(
84                  warning(
85                      "No method setFixture() in class "
86                          + fixtureClass.getName()));
87          }
88          catch (IllegalArgumentException e) {
89              addTest(
90                  warning(
91                      "Bad arguments to setFixture() in class "
92                          + fixtureClass.getName()));
93          }
94          catch (IllegalAccessException e) {
95              addTest(
96                  warning(
97                      "Insufficient access to invoke setFixture() in class "
98                          + fixtureClass.getName()));
99          }
100         catch (InvocationTargetException reported) {
101             addTest(
102                 warning(
103                     "setFixture() threw exception "
104                         + reported
105                         + "in class "
106                         + fixtureClass.getName()));
107         }
108     }
109 
110     private static Test warning(final String message) {
111         // TODO Make this public in TestSuite!
112         return new TestCase("warning") {
113             protected void runTest() {
114                 fail(message);
115             }
116         };
117     }
118 }