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 java.lang.reflect.InvocationTargetException;
23  import java.lang.reflect.Method;
24  import java.lang.reflect.Modifier;
25  import java.util.ArrayList;
26  import java.util.List;
27  import org.apache.maven.surefire.report.LegacyPojoStackTraceWriter;
28  import org.apache.maven.surefire.report.ReportEntry;
29  import org.apache.maven.surefire.report.RunListener;
30  import org.apache.maven.surefire.report.SimpleReportEntry;
31  import org.apache.maven.surefire.testset.TestSetFailedException;
32  
33  public class PojoTestSet
34      implements SurefireTestSet
35  {
36  
37      private static final String TEST_METHOD_PREFIX = "test";
38  
39      private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
40  
41      private final Object testObject;
42  
43      private List<Method> testMethods;
44  
45      private Method setUpMethod;
46  
47      private Method tearDownMethod;
48  
49      private final Class testClass;
50  
51      public PojoTestSet( Class testClass )
52          throws TestSetFailedException
53      {
54          if ( testClass == null )
55          {
56              throw new NullPointerException( "testClass is null" );
57          }
58  
59          this.testClass = testClass;
60  
61          try
62          {
63              testObject = testClass.newInstance();
64          }
65          catch ( InstantiationException e )
66          {
67              throw new TestSetFailedException( "Unable to instantiate POJO '" + testClass + "'", e );
68          }
69          catch ( IllegalAccessException e )
70          {
71              throw new TestSetFailedException( "Unable to instantiate POJO '" + testClass + "'", e );
72          }
73      }
74  
75      public void execute( RunListener reportManager, ClassLoader loader )
76          throws TestSetFailedException
77      {
78          if ( reportManager == null )
79          {
80              throw new NullPointerException( "reportManager is null" );
81          }
82  
83          executeTestMethods( reportManager );
84      }
85  
86      private void executeTestMethods( RunListener reportManager )
87      {
88          if ( reportManager == null )
89          {
90              throw new NullPointerException( "reportManager is null" );
91          }
92  
93          if ( testMethods == null )
94          {
95              discoverTestMethods();
96          }
97  
98          boolean abort = false;
99  
100         for ( int i = 0; i < testMethods.size() && !abort; ++i )
101         {
102             abort = executeTestMethod( testMethods.get( i ), EMPTY_OBJECT_ARRAY, reportManager );
103         }
104     }
105 
106     private boolean executeTestMethod( Method method, Object[] args, RunListener reportManager )
107     {
108         if ( method == null || args == null || reportManager == null )
109         {
110             throw new NullPointerException();
111         }
112 
113         String userFriendlyMethodName = method.getName() + '(';
114 
115         if ( args.length != 0 )
116         {
117             userFriendlyMethodName += "Reporter";
118         }
119 
120         userFriendlyMethodName += ')';
121 
122         ReportEntry report =
123             new SimpleReportEntry( testObject.getClass().getName(), getTestName( userFriendlyMethodName ) );
124 
125         reportManager.testStarting( report );
126 
127         try
128         {
129             setUpFixture();
130         }
131         catch ( Throwable e )
132         {
133             report =
134                 SimpleReportEntry.withException( testObject.getClass().getName(), getTestName( userFriendlyMethodName ),
135                                                  new LegacyPojoStackTraceWriter( testObject.getClass().getName(),
136                                                                                  method.getName(), e ) );
137 
138             reportManager.testFailed( report );
139 
140             
141             
142             
143             
144             
145             return true;
146         }
147 
148         
149         try
150         {
151             method.invoke( testObject, args );
152 
153             report = new SimpleReportEntry( testObject.getClass().getName(), getTestName( userFriendlyMethodName ) );
154 
155             reportManager.testSucceeded( report );
156         }
157         catch ( InvocationTargetException ite )
158         {
159             Throwable t = ite.getTargetException();
160 
161             report =
162                 SimpleReportEntry.withException( testObject.getClass().getName(), getTestName( userFriendlyMethodName ),
163                                                  new LegacyPojoStackTraceWriter( testObject.getClass().getName(),
164                                                                                  method.getName(), t ) );
165 
166             reportManager.testFailed( report );
167             
168             
169         }
170         catch ( Throwable t )
171         {
172             report =
173                 SimpleReportEntry.withException( testObject.getClass().getName(), getTestName( userFriendlyMethodName ),
174                                                  new LegacyPojoStackTraceWriter( testObject.getClass().getName(),
175                                                                                  method.getName(), t ) );
176 
177             reportManager.testFailed( report );
178             
179             
180         }
181 
182         try
183         {
184             tearDownFixture();
185         }
186         catch ( Throwable t )
187         {
188             
189             report =
190                 SimpleReportEntry.withException( testObject.getClass().getName(), getTestName( userFriendlyMethodName ),
191                                                  new LegacyPojoStackTraceWriter( testObject.getClass().getName(),
192                                                                                  method.getName(), t ) );
193 
194             reportManager.testFailed( report );
195 
196             
197             
198             
199             
200             
201             return true;
202         }
203 
204         
205         
206         
207         
208         
209         return false;
210     }
211 
212     private String getTestName( String testMethodName )
213     {
214         if ( testMethodName == null )
215         {
216             throw new NullPointerException( "testMethodName is null" );
217         }
218 
219         return getTestClass().getName() + "." + testMethodName;
220     }
221 
222     private void setUpFixture()
223         throws Throwable
224     {
225         if ( setUpMethod != null )
226         {
227             setUpMethod.invoke( testObject );
228         }
229     }
230 
231     private void tearDownFixture()
232         throws Throwable
233     {
234         if ( tearDownMethod != null )
235         {
236             tearDownMethod.invoke( testObject );
237         }
238     }
239 
240     private void discoverTestMethods()
241     {
242         if ( testMethods == null )
243         {
244             testMethods = new ArrayList<Method>();
245 
246             Method[] methods = getTestClass().getMethods();
247 
248             for ( Method m : methods )
249             {
250                 if ( isValidTestMethod( m ) )
251                 {
252                     String simpleName = m.getName();
253 
254                     
255                     if ( simpleName.length() > 4 )
256                     {
257                         String firstFour = simpleName.substring( 0, 4 );
258 
259                         
260                         if ( firstFour.equals( TEST_METHOD_PREFIX ) )
261                         {
262                             testMethods.add( m );
263                         }
264                     }
265                 }
266                 else if ( m.getName().equals( "setUp" ) && m.getParameterTypes().length == 0 )
267                 {
268                     setUpMethod = m;
269                 }
270                 else if ( m.getName().equals( "tearDown" ) && m.getParameterTypes().length == 0 )
271                 {
272                     tearDownMethod = m;
273                 }
274             }
275         }
276     }
277 
278     private static boolean isValidTestMethod( Method m )
279     {
280         boolean isInstanceMethod = !Modifier.isStatic( m.getModifiers() );
281 
282         boolean returnsVoid = m.getReturnType().equals( void.class );
283 
284         boolean hasNoParams = m.getParameterTypes().length == 0;
285 
286         return isInstanceMethod && returnsVoid && hasNoParams;
287     }
288 
289     public String getName()
290     {
291         return testClass.getName();
292     }
293 
294     public Class getTestClass()
295     {
296         return testClass;
297     }
298 }