1 package org.junit; 2 3 import java.lang.annotation.ElementType; 4 import java.lang.annotation.Retention; 5 import java.lang.annotation.RetentionPolicy; 6 import java.lang.annotation.Target; 7 8 /** 9 * Annotates static fields that reference rules or methods that return them. A field must be public, 10 * static, and a subtype of {@link org.junit.rules.TestRule}. A method must be public static, and return 11 * a subtype of {@link org.junit.rules.TestRule}. 12 * <p> 13 * The {@link org.junit.runners.model.Statement} passed 14 * to the {@link org.junit.rules.TestRule} will run any {@link BeforeClass} methods, 15 * then the entire body of the test class (all contained methods, if it is 16 * a standard JUnit test class, or all contained classes, if it is a 17 * {@link org.junit.runners.Suite}), and finally any {@link AfterClass} methods. 18 * <p> 19 * The statement passed to the {@link org.junit.rules.TestRule} will never throw an exception, 20 * and throwing an exception from the {@link org.junit.rules.TestRule} will result in undefined 21 * behavior. This means that some {@link org.junit.rules.TestRule}s, such as 22 * {@link org.junit.rules.ErrorCollector}, 23 * {@link org.junit.rules.ExpectedException}, 24 * and {@link org.junit.rules.Timeout}, 25 * have undefined behavior when used as {@link ClassRule}s. 26 * <p> 27 * If there are multiple 28 * annotated {@link ClassRule}s on a class, they will be applied in an order 29 * that depends on your JVM's implementation of the reflection API, which is 30 * undefined, in general. However, Rules defined by fields will always be applied 31 * after Rules defined by methods, i.e. the Statements returned by the former will 32 * be executed around those returned by the latter. 33 * 34 * <h3>Usage</h3> 35 * <p> 36 * For example, here is a test suite that connects to a server once before 37 * all the test classes run, and disconnects after they are finished: 38 * <pre> 39 * @RunWith(Suite.class) 40 * @SuiteClasses({A.class, B.class, C.class}) 41 * public class UsesExternalResource { 42 * public static Server myServer= new Server(); 43 * 44 * @ClassRule 45 * public static ExternalResource resource= new ExternalResource() { 46 * @Override 47 * protected void before() throws Throwable { 48 * myServer.connect(); 49 * } 50 * 51 * @Override 52 * protected void after() { 53 * myServer.disconnect(); 54 * } 55 * }; 56 * } 57 * </pre> 58 * <p> 59 * and the same using a method 60 * <pre> 61 * @RunWith(Suite.class) 62 * @SuiteClasses({A.class, B.class, C.class}) 63 * public class UsesExternalResource { 64 * public static Server myServer= new Server(); 65 * 66 * @ClassRule 67 * public static ExternalResource getResource() { 68 * return new ExternalResource() { 69 * @Override 70 * protected void before() throws Throwable { 71 * myServer.connect(); 72 * } 73 * 74 * @Override 75 * protected void after() { 76 * myServer.disconnect(); 77 * } 78 * }; 79 * } 80 * } 81 * </pre> 82 * <p> 83 * For more information and more examples, see {@link org.junit.rules.TestRule}. 84 * 85 * <h3>Ordering</h3> 86 * <p> 87 * You can use {@link #order()} if you want to have control over the order in 88 * which the Rules are applied. 89 * 90 * <pre> 91 * public class ThreeClassRules { 92 * @ClassRule(order = 0) 93 * public static LoggingRule outer = new LoggingRule("outer rule"); 94 * 95 * @ClassRule(order = 1) 96 * public static LoggingRule middle = new LoggingRule("middle rule"); 97 * 98 * @ClassRule(order = 2) 99 * public static LoggingRule inner = new LoggingRule("inner rule"); 100 * 101 * // ... 102 * } 103 * </pre> 104 * 105 * @since 4.9 106 */ 107 @Retention(RetentionPolicy.RUNTIME) 108 @Target({ElementType.FIELD, ElementType.METHOD}) 109 public @interface ClassRule { 110 111 /** 112 * Specifies the order in which rules are applied. The rules with a higher value are inner. 113 * 114 * @since 4.13 115 */ order()116 int order() default Rule.DEFAULT_ORDER; 117 118 } 119