1 package org.junit.tests.experimental.rules; 2 3 import static org.junit.Assert.assertEquals; 4 import static org.junit.internal.runners.rules.RuleMemberValidator.CLASS_RULE_METHOD_VALIDATOR; 5 import static org.junit.internal.runners.rules.RuleMemberValidator.CLASS_RULE_VALIDATOR; 6 import static org.junit.internal.runners.rules.RuleMemberValidator.RULE_METHOD_VALIDATOR; 7 import static org.junit.internal.runners.rules.RuleMemberValidator.RULE_VALIDATOR; 8 9 import java.util.ArrayList; 10 import java.util.List; 11 12 import org.junit.ClassRule; 13 import org.junit.Rule; 14 import org.junit.Test; 15 import org.junit.rules.MethodRule; 16 import org.junit.rules.TemporaryFolder; 17 import org.junit.rules.TestRule; 18 import org.junit.rules.TestWatchman; 19 import org.junit.runners.model.FrameworkMethod; 20 import org.junit.runners.model.Statement; 21 import org.junit.runners.model.TestClass; 22 23 public class RuleMemberValidatorTest { 24 private final List<Throwable> errors = new ArrayList<Throwable>(); 25 26 @Test 27 public void rejectProtectedClassRule() { 28 TestClass target = new TestClass(TestWithProtectedClassRule.class); 29 CLASS_RULE_VALIDATOR.validate(target, errors); 30 assertOneErrorWithMessage("The @ClassRule 'temporaryFolder' must be public."); 31 } 32 33 public static class TestWithProtectedClassRule { 34 @ClassRule 35 protected static TestRule temporaryFolder = new TemporaryFolder(); 36 } 37 38 @Test 39 public void rejectNonStaticClassRule() { 40 TestClass target = new TestClass(TestWithNonStaticClassRule.class); 41 CLASS_RULE_VALIDATOR.validate(target, errors); 42 assertOneErrorWithMessage("The @ClassRule 'temporaryFolder' must be static."); 43 } 44 45 public static class TestWithNonStaticClassRule { 46 @ClassRule 47 public TestRule temporaryFolder = new TemporaryFolder(); 48 } 49 50 @Test 51 public void acceptStaticTestRuleThatIsAlsoClassRule() { 52 TestClass target = new TestClass(TestWithStaticClassAndTestRule.class); 53 CLASS_RULE_VALIDATOR.validate(target, errors); 54 assertNumberOfErrors(0); 55 } 56 57 public static class TestWithStaticClassAndTestRule { 58 @ClassRule 59 @Rule 60 public static TestRule temporaryFolder = new TemporaryFolder(); 61 } 62 63 @Test 64 public void rejectClassRuleInNonPublicClass() { 65 TestClass target = new TestClass(NonPublicTestWithClassRule.class); 66 CLASS_RULE_VALIDATOR.validate(target, errors); 67 assertOneErrorWithMessage("The @ClassRule 'temporaryFolder' must be declared in a public class."); 68 } 69 70 static class NonPublicTestWithClassRule { 71 @ClassRule 72 public static TestRule temporaryFolder = new TemporaryFolder(); 73 } 74 75 @Test 76 public void acceptNonStaticTestRule() { 77 TestClass target = new TestClass(TestWithNonStaticTestRule.class); 78 RULE_VALIDATOR.validate(target, errors); 79 assertNumberOfErrors(0); 80 } 81 82 public static class TestWithNonStaticTestRule { 83 @Rule 84 public TestRule temporaryFolder = new TemporaryFolder(); 85 } 86 87 @Test 88 public void rejectStaticTestRule() { 89 TestClass target = new TestClass(TestWithStaticTestRule.class); 90 RULE_VALIDATOR.validate(target, errors); 91 assertOneErrorWithMessage("The @Rule 'temporaryFolder' must not be static or it must be annotated with @ClassRule."); 92 } 93 94 public static class TestWithStaticTestRule { 95 @Rule 96 public static TestRule temporaryFolder = new TemporaryFolder(); 97 } 98 99 @Test 100 public void rejectStaticMethodRule() { 101 TestClass target = new TestClass(TestWithStaticMethodRule.class); 102 RULE_VALIDATOR.validate(target, errors); 103 assertOneErrorWithMessage("The @Rule 'testWatchman' must not be static."); 104 } 105 106 public static class TestWithStaticMethodRule { 107 @SuppressWarnings("deprecation") 108 @Rule 109 public static MethodRule testWatchman = new TestWatchman(); 110 } 111 112 @Test 113 public void acceptMethodRule() throws Exception { 114 TestClass target = new TestClass(TestWithMethodRule.class); 115 RULE_VALIDATOR.validate(target, errors); 116 assertNumberOfErrors(0); 117 } 118 119 public static class TestWithMethodRule { 120 @Rule 121 public MethodRule temporaryFolder = new MethodRule() { 122 public Statement apply(Statement base, FrameworkMethod method, 123 Object target) { 124 return null; 125 } 126 }; 127 } 128 129 @Test 130 public void rejectArbitraryObjectWithRuleAnnotation() throws Exception { 131 TestClass target = new TestClass(TestWithArbitraryObjectWithRuleAnnotation.class); 132 RULE_VALIDATOR.validate(target, errors); 133 assertOneErrorWithMessage("The @Rule 'arbitraryObject' must implement MethodRule or TestRule."); 134 } 135 136 public static class TestWithArbitraryObjectWithRuleAnnotation { 137 @Rule 138 public Object arbitraryObject = 1; 139 } 140 141 @Test 142 public void methodRejectProtectedClassRule() { 143 TestClass target = new TestClass(MethodTestWithProtectedClassRule.class); 144 CLASS_RULE_METHOD_VALIDATOR.validate(target, errors); 145 assertOneErrorWithMessage("The @ClassRule 'getTemporaryFolder' must be public."); 146 } 147 148 public static class MethodTestWithProtectedClassRule { 149 @ClassRule 150 protected static TestRule getTemporaryFolder() { 151 return new TemporaryFolder(); 152 } 153 } 154 155 @Test 156 public void methodRejectNonStaticClassRule() { 157 TestClass target = new TestClass(MethodTestWithNonStaticClassRule.class); 158 CLASS_RULE_METHOD_VALIDATOR.validate(target, errors); 159 assertOneErrorWithMessage("The @ClassRule 'getTemporaryFolder' must be static."); 160 } 161 162 public static class MethodTestWithNonStaticClassRule { 163 @ClassRule 164 public TestRule getTemporaryFolder() { 165 return new TemporaryFolder(); 166 } 167 } 168 169 @Test 170 public void acceptMethodStaticTestRuleThatIsAlsoClassRule() { 171 TestClass target = new TestClass(MethodTestWithStaticClassAndTestRule.class); 172 CLASS_RULE_METHOD_VALIDATOR.validate(target, errors); 173 assertNumberOfErrors(0); 174 } 175 176 public static class MethodTestWithStaticClassAndTestRule { 177 @ClassRule 178 @Rule 179 public static TestRule getTemporaryFolder() { 180 return new TemporaryFolder(); 181 } 182 } 183 184 @Test 185 public void acceptMethodNonStaticTestRule() { 186 TestClass target = new TestClass(TestMethodWithNonStaticTestRule.class); 187 RULE_METHOD_VALIDATOR.validate(target, errors); 188 assertNumberOfErrors(0); 189 } 190 191 public static class TestMethodWithNonStaticTestRule { 192 @Rule 193 public TestRule getTemporaryFolder() { 194 return new TemporaryFolder(); 195 } 196 } 197 198 @Test 199 public void rejectMethodStaticTestRule() { 200 TestClass target = new TestClass(TestMethodWithStaticTestRule.class); 201 RULE_METHOD_VALIDATOR.validate(target, errors); 202 assertOneErrorWithMessage("The @Rule 'getTemporaryFolder' must not be static or it must be annotated with @ClassRule."); 203 } 204 205 public static class TestMethodWithStaticTestRule { 206 @Rule 207 public static TestRule getTemporaryFolder() { 208 return new TemporaryFolder(); 209 } 210 } 211 212 @Test 213 public void rejectMethodStaticMethodRule() { 214 TestClass target = new TestClass(TestMethodWithStaticMethodRule.class); 215 RULE_METHOD_VALIDATOR.validate(target, errors); 216 assertOneErrorWithMessage("The @Rule 'getTestWatchman' must not be static."); 217 } 218 219 public static class TestMethodWithStaticMethodRule { 220 @SuppressWarnings("deprecation") 221 @Rule 222 public static MethodRule getTestWatchman() { return new TestWatchman(); } 223 } 224 225 @Test 226 public void methodAcceptMethodRuleMethod() throws Exception { 227 TestClass target = new TestClass(MethodTestWithMethodRule.class); 228 RULE_METHOD_VALIDATOR.validate(target, errors); 229 assertNumberOfErrors(0); 230 } 231 232 public static class MethodTestWithMethodRule { 233 @Rule 234 public MethodRule getTemporaryFolder() { 235 return new MethodRule() { 236 public Statement apply(Statement base, FrameworkMethod method, 237 Object target) { 238 return null; 239 } 240 }; 241 } 242 } 243 244 @Test 245 public void methodRejectArbitraryObjectWithRuleAnnotation() throws Exception { 246 TestClass target = new TestClass(MethodTestWithArbitraryObjectWithRuleAnnotation.class); 247 RULE_METHOD_VALIDATOR.validate(target, errors); 248 assertOneErrorWithMessage("The @Rule 'getArbitraryObject' must return an implementation of MethodRule or TestRule."); 249 } 250 251 public static class MethodTestWithArbitraryObjectWithRuleAnnotation { 252 @Rule 253 public Object getArbitraryObject() { 254 return 1; 255 } 256 } 257 258 private void assertOneErrorWithMessage(String message) { 259 assertNumberOfErrors(1); 260 assertEquals("Wrong error message:", message, errors.get(0).getMessage()); 261 } 262 263 private void assertNumberOfErrors(int numberOfErrors) { 264 assertEquals("Wrong number of errors:", numberOfErrors, errors.size()); 265 } 266 }