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 fields that reference rules or methods that return a rule. A field must be public, not 010 * static, and a subtype of {@link org.junit.rules.TestRule} (preferred) or 011 * {@link org.junit.rules.MethodRule}. A method must be public, not static, 012 * and must return a subtype of {@link org.junit.rules.TestRule} (preferred) or 013 * {@link org.junit.rules.MethodRule}. 014 * <p> 015 * The {@link org.junit.runners.model.Statement} passed 016 * to the {@link org.junit.rules.TestRule} will run any {@link Before} methods, 017 * then the {@link Test} method, and finally any {@link After} methods, 018 * throwing an exception if any of these fail. If there are multiple 019 * annotated {@link Rule}s on a class, they will be applied in order of methods first, then fields. 020 * However, if there are multiple fields (or methods) they will be applied in an order 021 * that depends on your JVM's implementation of the reflection API, which is 022 * undefined, in general. Rules defined by fields will always be applied 023 * after Rules defined by methods, i.e. the Statements returned by the former will 024 * be executed around those returned by the latter. 025 * 026 * <h3>Usage</h3> 027 * <p> 028 * For example, here is a test class that creates a temporary folder before 029 * each test method, and deletes it after each: 030 * <pre> 031 * public static class HasTempFolder { 032 * @Rule 033 * public TemporaryFolder folder= new TemporaryFolder(); 034 * 035 * @Test 036 * public void testUsingTempFolder() throws IOException { 037 * File createdFile= folder.newFile("myfile.txt"); 038 * File createdFolder= folder.newFolder("subfolder"); 039 * // ... 040 * } 041 * } 042 * </pre> 043 * <p> 044 * And the same using a method. 045 * <pre> 046 * public static class HasTempFolder { 047 * private TemporaryFolder folder= new TemporaryFolder(); 048 * 049 * @Rule 050 * public TemporaryFolder getFolder() { 051 * return folder; 052 * } 053 * 054 * @Test 055 * public void testUsingTempFolder() throws IOException { 056 * File createdFile= folder.newFile("myfile.txt"); 057 * File createdFolder= folder.newFolder("subfolder"); 058 * // ... 059 * } 060 * } 061 * </pre> 062 * <p> 063 * For more information and more examples, see 064 * {@link org.junit.rules.TestRule}. 065 * 066 * <h3>Ordering</h3> 067 * <p> 068 * You can use {@link #order()} if you want to have control over the order in 069 * which the Rules are applied. 070 * 071 * <pre> 072 * public class ThreeRules { 073 * @Rule(order = 0) 074 * public LoggingRule outer = new LoggingRule("outer rule"); 075 * 076 * @Rule(order = 1) 077 * public LoggingRule middle = new LoggingRule("middle rule"); 078 * 079 * @Rule(order = 2) 080 * public LoggingRule inner = new LoggingRule("inner rule"); 081 * 082 * // ... 083 * } 084 * </pre> 085 * 086 * @since 4.7 087 */ 088 @Retention(RetentionPolicy.RUNTIME) 089 @Target({ElementType.FIELD, ElementType.METHOD}) 090 public @interface Rule { 091 092 int DEFAULT_ORDER = -1; 093 094 /** 095 * Specifies the order in which rules are applied. The rules with a higher value are inner. 096 * 097 * @since 4.13 098 */ 099 int order() default DEFAULT_ORDER; 100 101 }