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
112 return new TestCase("warning") {
113 protected void runTest() {
114 fail(message);
115 }
116 };
117 }
118 }