001 package org.junit;
002
003 import java.lang.annotation.ElementType;
004 import java.lang.annotation.Retention;
005 import java.lang.annotation.RetentionPolicy;
006 import java.lang.annotation.Target;
007
008 /**
009 * Annotates static fields that reference rules or methods that return them. A field must be public,
010 * static, and a subtype of {@link org.junit.rules.TestRule}. A method must be public static, and return
011 * a subtype of {@link org.junit.rules.TestRule}.
012 * <p>
013 * The {@link org.junit.runners.model.Statement} passed
014 * to the {@link org.junit.rules.TestRule} will run any {@link BeforeClass} methods,
015 * then the entire body of the test class (all contained methods, if it is
016 * a standard JUnit test class, or all contained classes, if it is a
017 * {@link org.junit.runners.Suite}), and finally any {@link AfterClass} methods.
018 * <p>
019 * The statement passed to the {@link org.junit.rules.TestRule} will never throw an exception,
020 * and throwing an exception from the {@link org.junit.rules.TestRule} will result in undefined
021 * behavior. This means that some {@link org.junit.rules.TestRule}s, such as
022 * {@link org.junit.rules.ErrorCollector},
023 * {@link org.junit.rules.ExpectedException},
024 * and {@link org.junit.rules.Timeout},
025 * have undefined behavior when used as {@link ClassRule}s.
026 * <p>
027 * If there are multiple
028 * annotated {@link ClassRule}s on a class, they will be applied in an order
029 * that depends on your JVM's implementation of the reflection API, which is
030 * undefined, in general. However, Rules defined by fields will always be applied
031 * after Rules defined by methods, i.e. the Statements returned by the former will
032 * be executed around those returned by the latter.
033 *
034 * <h3>Usage</h3>
035 * <p>
036 * For example, here is a test suite that connects to a server once before
037 * all the test classes run, and disconnects after they are finished:
038 * <pre>
039 * @RunWith(Suite.class)
040 * @SuiteClasses({A.class, B.class, C.class})
041 * public class UsesExternalResource {
042 * public static Server myServer= new Server();
043 *
044 * @ClassRule
045 * public static ExternalResource resource= new ExternalResource() {
046 * @Override
047 * protected void before() throws Throwable {
048 * myServer.connect();
049 * }
050 *
051 * @Override
052 * protected void after() {
053 * myServer.disconnect();
054 * }
055 * };
056 * }
057 * </pre>
058 * <p>
059 * and the same using a method
060 * <pre>
061 * @RunWith(Suite.class)
062 * @SuiteClasses({A.class, B.class, C.class})
063 * public class UsesExternalResource {
064 * public static Server myServer= new Server();
065 *
066 * @ClassRule
067 * public static ExternalResource getResource() {
068 * return new ExternalResource() {
069 * @Override
070 * protected void before() throws Throwable {
071 * myServer.connect();
072 * }
073 *
074 * @Override
075 * protected void after() {
076 * myServer.disconnect();
077 * }
078 * };
079 * }
080 * }
081 * </pre>
082 * <p>
083 * For more information and more examples, see {@link org.junit.rules.TestRule}.
084 *
085 * <h3>Ordering</h3>
086 * <p>
087 * You can use {@link #order()} if you want to have control over the order in
088 * which the Rules are applied.
089 *
090 * <pre>
091 * public class ThreeClassRules {
092 * @ClassRule(order = 0)
093 * public static LoggingRule outer = new LoggingRule("outer rule");
094 *
095 * @ClassRule(order = 1)
096 * public static LoggingRule middle = new LoggingRule("middle rule");
097 *
098 * @ClassRule(order = 2)
099 * 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 */
116 int order() default Rule.DEFAULT_ORDER;
117
118 }