001package org.junit.runners; 002 003import static org.junit.internal.runners.rules.RuleFieldValidator.RULE_METHOD_VALIDATOR; 004import static org.junit.internal.runners.rules.RuleFieldValidator.RULE_VALIDATOR; 005 006import java.util.List; 007 008import org.junit.After; 009import org.junit.Before; 010import org.junit.Ignore; 011import org.junit.Rule; 012import org.junit.Test; 013import org.junit.Test.None; 014import org.junit.internal.runners.model.ReflectiveCallable; 015import org.junit.internal.runners.statements.ExpectException; 016import org.junit.internal.runners.statements.Fail; 017import org.junit.internal.runners.statements.FailOnTimeout; 018import org.junit.internal.runners.statements.InvokeMethod; 019import org.junit.internal.runners.statements.RunAfters; 020import org.junit.internal.runners.statements.RunBefores; 021import org.junit.rules.RunRules; 022import org.junit.rules.TestRule; 023import org.junit.runner.Description; 024import org.junit.runner.notification.RunNotifier; 025import org.junit.runners.model.FrameworkMethod; 026import org.junit.runners.model.InitializationError; 027import org.junit.runners.model.MultipleFailureException; 028import org.junit.runners.model.Statement; 029 030/** 031 * Implements the JUnit 4 standard test case class model, as defined by the 032 * annotations in the org.junit package. Many users will never notice this 033 * class: it is now the default test class runner, but it should have exactly 034 * the same behavior as the old test class runner ({@code JUnit4ClassRunner}). 035 * 036 * BlockJUnit4ClassRunner has advantages for writers of custom JUnit runners 037 * that are slight changes to the default behavior, however: 038 * 039 * <ul> 040 * <li>It has a much simpler implementation based on {@link Statement}s, 041 * allowing new operations to be inserted into the appropriate point in the 042 * execution flow. 043 * 044 * <li>It is published, and extension and reuse are encouraged, whereas {@code 045 * JUnit4ClassRunner} was in an internal package, and is now deprecated. 046 * </ul> 047 * 048 * @since 4.5 049 */ 050public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> { 051 /** 052 * Creates a BlockJUnit4ClassRunner to run {@code klass} 053 * 054 * @throws InitializationError if the test class is malformed. 055 */ 056 public BlockJUnit4ClassRunner(Class<?> klass) throws InitializationError { 057 super(klass); 058 } 059 060 // 061 // Implementation of ParentRunner 062 // 063 064 @Override 065 protected void runChild(final FrameworkMethod method, RunNotifier notifier) { 066 Description description = describeChild(method); 067 if (method.getAnnotation(Ignore.class) != null) { 068 notifier.fireTestIgnored(description); 069 } else { 070 runLeaf(methodBlock(method), description, notifier); 071 } 072 } 073 074 @Override 075 protected Description describeChild(FrameworkMethod method) { 076 return Description.createTestDescription(getTestClass().getJavaClass(), 077 testName(method), method.getAnnotations()); 078 } 079 080 @Override 081 protected List<FrameworkMethod> getChildren() { 082 return computeTestMethods(); 083 } 084 085 // 086 // Override in subclasses 087 // 088 089 /** 090 * Returns the methods that run tests. Default implementation returns all 091 * methods annotated with {@code @Test} on this class and superclasses that 092 * are not overridden. 093 */ 094 protected List<FrameworkMethod> computeTestMethods() { 095 return getTestClass().getAnnotatedMethods(Test.class); 096 } 097 098 @Override 099 protected void collectInitializationErrors(List<Throwable> errors) { 100 super.collectInitializationErrors(errors); 101 102 validateNoNonStaticInnerClass(errors); 103 validateConstructor(errors); 104 validateInstanceMethods(errors); 105 validateFields(errors); 106 validateMethods(errors); 107 } 108 109 protected void validateNoNonStaticInnerClass(List<Throwable> errors) { 110 if (getTestClass().isANonStaticInnerClass()) { 111 String gripe = "The inner class " + getTestClass().getName() 112 + " is not static."; 113 errors.add(new Exception(gripe)); 114 } 115 } 116 117 /** 118 * Adds to {@code errors} if the test class has more than one constructor, 119 * or if the constructor takes parameters. Override if a subclass requires 120 * different validation rules. 121 */ 122 protected void validateConstructor(List<Throwable> errors) { 123 validateOnlyOneConstructor(errors); 124 validateZeroArgConstructor(errors); 125 } 126 127 /** 128 * Adds to {@code errors} if the test class has more than one constructor 129 * (do not override) 130 */ 131 protected void validateOnlyOneConstructor(List<Throwable> errors) { 132 if (!hasOneConstructor()) { 133 String gripe = "Test class should have exactly one public constructor"; 134 errors.add(new Exception(gripe)); 135 } 136 } 137 138 /** 139 * Adds to {@code errors} if the test class's single constructor takes 140 * parameters (do not override) 141 */ 142 protected void validateZeroArgConstructor(List<Throwable> errors) { 143 if (!getTestClass().isANonStaticInnerClass() 144 && hasOneConstructor() 145 && (getTestClass().getOnlyConstructor().getParameterTypes().length != 0)) { 146 String gripe = "Test class should have exactly one public zero-argument constructor"; 147 errors.add(new Exception(gripe)); 148 } 149 } 150 151 private boolean hasOneConstructor() { 152 return getTestClass().getJavaClass().getConstructors().length == 1; 153 } 154 155 /** 156 * Adds to {@code errors} for each method annotated with {@code @Test}, 157 * {@code @Before}, or {@code @After} that is not a public, void instance 158 * method with no arguments. 159 * 160 * @deprecated unused API, will go away in future version 161 */ 162 @Deprecated 163 protected void validateInstanceMethods(List<Throwable> errors) { 164 validatePublicVoidNoArgMethods(After.class, false, errors); 165 validatePublicVoidNoArgMethods(Before.class, false, errors); 166 validateTestMethods(errors); 167 168 if (computeTestMethods().size() == 0) { 169 errors.add(new Exception("No runnable methods")); 170 } 171 } 172 173 protected void validateFields(List<Throwable> errors) { 174 RULE_VALIDATOR.validate(getTestClass(), errors); 175 } 176 177 private void validateMethods(List<Throwable> errors) { 178 RULE_METHOD_VALIDATOR.validate(getTestClass(), errors); 179 } 180 181 /** 182 * Adds to {@code errors} for each method annotated with {@code @Test}that 183 * is not a public, void instance method with no arguments. 184 */ 185 protected void validateTestMethods(List<Throwable> errors) { 186 validatePublicVoidNoArgMethods(Test.class, false, errors); 187 } 188 189 /** 190 * Returns a new fixture for running a test. Default implementation executes 191 * the test class's no-argument constructor (validation should have ensured 192 * one exists). 193 */ 194 protected Object createTest() throws Exception { 195 return getTestClass().getOnlyConstructor().newInstance(); 196 } 197 198 /** 199 * Returns the name that describes {@code method} for {@link Description}s. 200 * Default implementation is the method's name 201 */ 202 protected String testName(FrameworkMethod method) { 203 return method.getName(); 204 } 205 206 /** 207 * Returns a Statement that, when executed, either returns normally if 208 * {@code method} passes, or throws an exception if {@code method} fails. 209 * 210 * Here is an outline of the default implementation: 211 * 212 * <ul> 213 * <li>Invoke {@code method} on the result of {@code createTest()}, and 214 * throw any exceptions thrown by either operation. 215 * <li>HOWEVER, if {@code method}'s {@code @Test} annotation has the {@code 216 * expecting} attribute, return normally only if the previous step threw an 217 * exception of the correct type, and throw an exception otherwise. 218 * <li>HOWEVER, if {@code method}'s {@code @Test} annotation has the {@code 219 * timeout} attribute, throw an exception if the previous step takes more 220 * than the specified number of milliseconds. 221 * <li>ALWAYS run all non-overridden {@code @Before} methods on this class 222 * and superclasses before any of the previous steps; if any throws an 223 * Exception, stop execution and pass the exception on. 224 * <li>ALWAYS run all non-overridden {@code @After} methods on this class 225 * and superclasses after any of the previous steps; all After methods are 226 * always executed: exceptions thrown by previous steps are combined, if 227 * necessary, with exceptions from After methods into a 228 * {@link MultipleFailureException}. 229 * <li>ALWAYS allow {@code @Rule} fields to modify the execution of the 230 * above steps. A {@code Rule} may prevent all execution of the above steps, 231 * or add additional behavior before and after, or modify thrown exceptions. 232 * For more information, see {@link TestRule} 233 * </ul> 234 * 235 * This can be overridden in subclasses, either by overriding this method, 236 * or the implementations creating each sub-statement. 237 */ 238 protected Statement methodBlock(FrameworkMethod method) { 239 Object test; 240 try { 241 test = new ReflectiveCallable() { 242 @Override 243 protected Object runReflectiveCall() throws Throwable { 244 return createTest(); 245 } 246 }.run(); 247 } catch (Throwable e) { 248 return new Fail(e); 249 } 250 251 Statement statement = methodInvoker(method, test); 252 statement = possiblyExpectingExceptions(method, test, statement); 253 statement = withPotentialTimeout(method, test, statement); 254 statement = withBefores(method, test, statement); 255 statement = withAfters(method, test, statement); 256 statement = withRules(method, test, statement); 257 return statement; 258 } 259 260 // 261 // Statement builders 262 // 263 264 /** 265 * Returns a {@link Statement} that invokes {@code method} on {@code test} 266 */ 267 protected Statement methodInvoker(FrameworkMethod method, Object test) { 268 return new InvokeMethod(method, test); 269 } 270 271 /** 272 * Returns a {@link Statement}: if {@code method}'s {@code @Test} annotation 273 * has the {@code expecting} attribute, return normally only if {@code next} 274 * throws an exception of the correct type, and throw an exception 275 * otherwise. 276 * 277 * @deprecated Will be private soon: use Rules instead 278 */ 279 @Deprecated 280 protected Statement possiblyExpectingExceptions(FrameworkMethod method, 281 Object test, Statement next) { 282 Test annotation = method.getAnnotation(Test.class); 283 return expectsException(annotation) ? new ExpectException(next, 284 getExpectedException(annotation)) : next; 285 } 286 287 /** 288 * Returns a {@link Statement}: if {@code method}'s {@code @Test} annotation 289 * has the {@code timeout} attribute, throw an exception if {@code next} 290 * takes more than the specified number of milliseconds. 291 * 292 * @deprecated Will be private soon: use Rules instead 293 */ 294 @Deprecated 295 protected Statement withPotentialTimeout(FrameworkMethod method, 296 Object test, Statement next) { 297 long timeout = getTimeout(method.getAnnotation(Test.class)); 298 return timeout > 0 ? new FailOnTimeout(next, timeout) : next; 299 } 300 301 /** 302 * Returns a {@link Statement}: run all non-overridden {@code @Before} 303 * methods on this class and superclasses before running {@code next}; if 304 * any throws an Exception, stop execution and pass the exception on. 305 */ 306 protected Statement withBefores(FrameworkMethod method, Object target, 307 Statement statement) { 308 List<FrameworkMethod> befores = getTestClass().getAnnotatedMethods( 309 Before.class); 310 return befores.isEmpty() ? statement : new RunBefores(statement, 311 befores, target); 312 } 313 314 /** 315 * Returns a {@link Statement}: run all non-overridden {@code @After} 316 * methods on this class and superclasses before running {@code next}; all 317 * After methods are always executed: exceptions thrown by previous steps 318 * are combined, if necessary, with exceptions from After methods into a 319 * {@link MultipleFailureException}. 320 */ 321 protected Statement withAfters(FrameworkMethod method, Object target, 322 Statement statement) { 323 List<FrameworkMethod> afters = getTestClass().getAnnotatedMethods( 324 After.class); 325 return afters.isEmpty() ? statement : new RunAfters(statement, afters, 326 target); 327 } 328 329 private Statement withRules(FrameworkMethod method, Object target, 330 Statement statement) { 331 List<TestRule> testRules = getTestRules(target); 332 Statement result = statement; 333 result = withMethodRules(method, testRules, target, result); 334 result = withTestRules(method, testRules, result); 335 336 return result; 337 } 338 339 private Statement withMethodRules(FrameworkMethod method, List<TestRule> testRules, 340 Object target, Statement result) { 341 for (org.junit.rules.MethodRule each : getMethodRules(target)) { 342 if (!testRules.contains(each)) { 343 result = each.apply(result, method, target); 344 } 345 } 346 return result; 347 } 348 349 private List<org.junit.rules.MethodRule> getMethodRules(Object target) { 350 return rules(target); 351 } 352 353 /** 354 * @param target the test case instance 355 * @return a list of MethodRules that should be applied when executing this 356 * test 357 */ 358 protected List<org.junit.rules.MethodRule> rules(Object target) { 359 return getTestClass().getAnnotatedFieldValues(target, Rule.class, 360 org.junit.rules.MethodRule.class); 361 } 362 363 /** 364 * Returns a {@link Statement}: apply all non-static {@link Value} fields 365 * annotated with {@link Rule}. 366 * 367 * @param statement The base statement 368 * @return a RunRules statement if any class-level {@link Rule}s are 369 * found, or the base statement 370 */ 371 private Statement withTestRules(FrameworkMethod method, List<TestRule> testRules, 372 Statement statement) { 373 return testRules.isEmpty() ? statement : 374 new RunRules(statement, testRules, describeChild(method)); 375 } 376 377 /** 378 * @param target the test case instance 379 * @return a list of TestRules that should be applied when executing this 380 * test 381 */ 382 protected List<TestRule> getTestRules(Object target) { 383 List<TestRule> result = getTestClass().getAnnotatedMethodValues(target, 384 Rule.class, TestRule.class); 385 386 result.addAll(getTestClass().getAnnotatedFieldValues(target, 387 Rule.class, TestRule.class)); 388 389 return result; 390 } 391 392 private Class<? extends Throwable> getExpectedException(Test annotation) { 393 if (annotation == null || annotation.expected() == None.class) { 394 return null; 395 } else { 396 return annotation.expected(); 397 } 398 } 399 400 private boolean expectsException(Test annotation) { 401 return getExpectedException(annotation) != null; 402 } 403 404 private long getTimeout(Test annotation) { 405 if (annotation == null) { 406 return 0; 407 } 408 return annotation.timeout(); 409 } 410}