1 package org.apache.maven.surefire.junit;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.surefire.report.ReporterManager;
23 import org.apache.maven.surefire.testset.AbstractTestSet;
24 import org.apache.maven.surefire.testset.TestSetFailedException;
25
26 import java.lang.reflect.Constructor;
27 import java.lang.reflect.InvocationTargetException;
28 import java.lang.reflect.Method;
29 import java.lang.reflect.Modifier;
30 import java.lang.reflect.Proxy;
31
32 public final class JUnitTestSet
33 extends AbstractTestSet
34 {
35 public static final String TEST_CASE = "junit.framework.Test";
36
37 public static final String TEST_RESULT = "junit.framework.TestResult";
38
39 public static final String TEST_LISTENER = "junit.framework.TestListener";
40
41 public static final String TEST = "junit.framework.Test";
42
43 public static final String ADD_LISTENER_METHOD = "addListener";
44
45 public static final String RUN_METHOD = "run";
46
47 public static final String COUNT_TEST_CASES_METHOD = "countTestCases";
48
49 public static final String SETUP_METHOD = "setUp";
50
51 public static final String TEARDOWN_METHOD = "tearDown";
52
53 private static final String TEST_SUITE = "junit.framework.TestSuite";
54
55 private Class[] interfacesImplementedByDynamicProxy;
56
57 private Class testResultClass;
58
59 private Method addListenerMethod;
60
61 private Method countTestCasesMethod;
62
63 private Method runMethod;
64
65 private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
66
67 private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
68
69 public JUnitTestSet( Class testClass )
70 throws TestSetFailedException
71 {
72 super( testClass );
73
74 processTestClass();
75 }
76
77 private void processTestClass()
78 throws TestSetFailedException
79 {
80 try
81 {
82 Class testClass = getTestClass();
83 ClassLoader loader = testClass.getClassLoader();
84
85 testResultClass = loader.loadClass( TEST_RESULT );
86
87 Class testListenerInterface = loader.loadClass( TEST_LISTENER );
88
89 Class testInterface = loader.loadClass( TEST );
90
91
92
93
94
95
96
97
98
99
100
101
102 interfacesImplementedByDynamicProxy = new Class[1];
103
104 interfacesImplementedByDynamicProxy[0] = testListenerInterface;
105
106
107
108 Class[] addListenerParamTypes = interfacesImplementedByDynamicProxy;
109
110 addListenerMethod = testResultClass.getMethod( ADD_LISTENER_METHOD, addListenerParamTypes );
111
112 if ( testInterface.isAssignableFrom( testClass ) )
113 {
114 countTestCasesMethod = testInterface.getMethod( COUNT_TEST_CASES_METHOD, EMPTY_CLASS_ARRAY );
115
116 runMethod = testInterface.getMethod( RUN_METHOD, new Class[]{testResultClass} );
117
118 }
119 else
120 {
121 countTestCasesMethod = testClass.getMethod( COUNT_TEST_CASES_METHOD, EMPTY_CLASS_ARRAY );
122
123 runMethod = testClass.getMethod( RUN_METHOD, new Class[]{testResultClass} );
124 }
125 }
126 catch ( ClassNotFoundException e )
127 {
128 throw new TestSetFailedException( "JUnit classes not available", e );
129 }
130 catch ( NoSuchMethodException e )
131 {
132 throw new TestSetFailedException( "Class is not a JUnit TestCase", e );
133 }
134 }
135
136 private static Object constructTestObject( Class testClass )
137 throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException,
138 ClassNotFoundException
139 {
140 Object testObject = createInstanceFromSuiteMethod( testClass );
141
142 if ( testObject == null && testClass.getClassLoader().loadClass( TEST_CASE ).isAssignableFrom( testClass ) )
143 {
144 Class[] constructorParamTypes = {Class.class};
145
146 Constructor constructor =
147 testClass.getClassLoader().loadClass( TEST_SUITE ).getConstructor( constructorParamTypes );
148
149 Object[] constructorParams = {testClass};
150
151 testObject = constructor.newInstance( constructorParams );
152 }
153
154 if ( testObject == null )
155 {
156 Constructor testConstructor = getTestConstructor( testClass );
157
158 if ( testConstructor.getParameterTypes().length == 0 )
159 {
160 testObject = testConstructor.newInstance( EMPTY_OBJECT_ARRAY );
161 }
162 else
163 {
164 testObject = testConstructor.newInstance( new Object[]{testClass.getName()} );
165 }
166 }
167 return testObject;
168 }
169
170 private static Object createInstanceFromSuiteMethod( Class testClass )
171 throws IllegalAccessException, InvocationTargetException
172 {
173 Object testObject = null;
174 try
175 {
176 Method suiteMethod = testClass.getMethod( "suite", EMPTY_CLASS_ARRAY );
177
178 if ( Modifier.isPublic( suiteMethod.getModifiers() ) && Modifier.isStatic( suiteMethod.getModifiers() ) )
179 {
180 testObject = suiteMethod.invoke( null, EMPTY_CLASS_ARRAY );
181 }
182 }
183 catch ( NoSuchMethodException e )
184 {
185
186 }
187 return testObject;
188 }
189
190 public void execute( ReporterManager reportManager, ClassLoader loader )
191 throws TestSetFailedException
192 {
193 Class testClass = getTestClass();
194
195 try
196 {
197 Object testObject = constructTestObject( testClass );
198
199 Object instanceOfTestResult = testResultClass.newInstance();
200
201 TestListenerInvocationHandler invocationHandler =
202 new TestListenerInvocationHandler( reportManager, instanceOfTestResult, loader );
203
204 Object testListener =
205 Proxy.newProxyInstance( loader, interfacesImplementedByDynamicProxy, invocationHandler );
206
207 Object[] addTestListenerParams = {testListener};
208
209 addListenerMethod.invoke( instanceOfTestResult, addTestListenerParams );
210
211 Object[] runParams = {instanceOfTestResult};
212
213 runMethod.invoke( testObject, runParams );
214 }
215 catch ( IllegalArgumentException e )
216 {
217 throw new TestSetFailedException( testClass.getName(), e );
218 }
219 catch ( InstantiationException e )
220 {
221 throw new TestSetFailedException( testClass.getName(), e );
222 }
223 catch ( IllegalAccessException e )
224 {
225 throw new TestSetFailedException( testClass.getName(), e );
226 }
227 catch ( InvocationTargetException e )
228 {
229 throw new TestSetFailedException( testClass.getName(), e.getTargetException() );
230 }
231 catch ( ClassNotFoundException e )
232 {
233 throw new TestSetFailedException( "JUnit classes not available", e );
234 }
235 catch ( NoSuchMethodException e )
236 {
237 throw new TestSetFailedException( "Class is not a JUnit TestCase", e );
238 }
239 }
240
241 private static Constructor getTestConstructor( Class testClass )
242 throws NoSuchMethodException
243 {
244 Constructor constructor;
245 try
246 {
247 constructor = testClass.getConstructor( new Class[]{String.class} );
248 }
249 catch ( NoSuchMethodException e )
250 {
251 constructor = testClass.getConstructor( EMPTY_CLASS_ARRAY );
252 }
253 return constructor;
254 }
255 }