View Javadoc
1   package org.junit.tests.experimental.rules;
2   
3   import static org.hamcrest.CoreMatchers.containsString;
4   import static org.hamcrest.CoreMatchers.is;
5   import static org.junit.Assert.assertEquals;
6   import static org.junit.Assert.assertThat;
7   import static org.junit.Assert.assertTrue;
8   import static org.junit.Assert.fail;
9   import static org.junit.experimental.results.PrintableResult.testResult;
10  import static org.junit.experimental.results.ResultMatchers.hasSingleFailureContaining;
11  import static org.junit.experimental.results.ResultMatchers.isSuccessful;
12  
13  import java.util.LinkedList;
14  import java.util.List;
15  
16  import org.junit.After;
17  import org.junit.Assume;
18  import org.junit.Before;
19  import org.junit.Rule;
20  import org.junit.Test;
21  import org.junit.internal.AssumptionViolatedException;
22  import org.junit.rules.TestName;
23  import org.junit.rules.TestRule;
24  import org.junit.rules.TestWatcher;
25  import org.junit.runner.Description;
26  import org.junit.runner.JUnitCore;
27  import org.junit.runner.Result;
28  import org.junit.runners.model.FrameworkMethod;
29  import org.junit.runners.model.Statement;
30  
31  public class TestRuleTest {
32      private static boolean wasRun;
33  
34      public static class ExampleTest {
35          @Rule
36          public TestRule example = new TestRule() {
37              public Statement apply(final Statement base, Description description) {
38                  return new Statement() {
39                      @Override
40                      public void evaluate() throws Throwable {
41                          wasRun = true;
42                          base.evaluate();
43                      }
44  
45                      ;
46                  };
47              }
48          };
49  
50          @Test
51          public void nothing() {
52  
53          }
54      }
55  
56      @Test
57      public void ruleIsIntroducedAndEvaluated() {
58          wasRun = false;
59          JUnitCore.runClasses(ExampleTest.class);
60          assertTrue(wasRun);
61      }
62  
63      public static class BothKindsOfRule implements TestRule, org.junit.rules.MethodRule {
64          public int applications = 0;
65  
66          public Statement apply(Statement base, FrameworkMethod method,
67                  Object target) {
68              applications++;
69              return base;
70          }
71  
72          public Statement apply(Statement base, Description description) {
73              applications++;
74              return base;
75          }
76      }
77  
78      public static class OneFieldTwoKindsOfRule {
79          @Rule
80          public BothKindsOfRule both = new BothKindsOfRule();
81  
82          @Test
83          public void onlyOnce() {
84              assertEquals(1, both.applications);
85          }
86      }
87  
88  
89      @Test
90      public void onlyApplyOnceEvenIfImplementsBothInterfaces() {
91          assertTrue(JUnitCore.runClasses(OneFieldTwoKindsOfRule.class).wasSuccessful());
92      }
93  
94      public static class SonOfExampleTest extends ExampleTest {
95  
96      }
97  
98      @Test
99      public void ruleIsIntroducedAndEvaluatedOnSubclass() {
100         wasRun = false;
101         JUnitCore.runClasses(SonOfExampleTest.class);
102         assertTrue(wasRun);
103     }
104 
105     private static int runCount;
106 
107     public static class MultipleRuleTest {
108         private static class Increment implements TestRule {
109             public Statement apply(final Statement base, Description description) {
110                 return new Statement() {
111                     @Override
112                     public void evaluate() throws Throwable {
113                         runCount++;
114                         base.evaluate();
115                     }
116 
117                     ;
118                 };
119             }
120         }
121 
122         @Rule
123         public TestRule incrementor1 = new Increment();
124 
125         @Rule
126         public TestRule incrementor2 = new Increment();
127 
128         @Test
129         public void nothing() {
130 
131         }
132     }
133 
134     @Test
135     public void multipleRulesAreRun() {
136         runCount = 0;
137         JUnitCore.runClasses(MultipleRuleTest.class);
138         assertEquals(2, runCount);
139     }
140 
141     public static class NoRulesTest {
142         public int x;
143 
144         @Test
145         public void nothing() {
146 
147         }
148     }
149 
150     @Test
151     public void ignoreNonRules() {
152         Result result = JUnitCore.runClasses(NoRulesTest.class);
153         assertEquals(0, result.getFailureCount());
154     }
155 
156     private static String log;
157 
158     public static class OnFailureTest {
159         @Rule
160         public TestRule watcher = new TestWatcher() {
161             @Override
162             protected void failed(Throwable e, Description description) {
163                 log += description + " " + e.getClass().getSimpleName();
164             }
165         };
166 
167         @Test
168         public void nothing() {
169             fail();
170         }
171     }
172 
173     @Test
174     public void onFailure() {
175         log = "";
176         Result result = JUnitCore.runClasses(OnFailureTest.class);
177         assertEquals(String.format("nothing(%s) AssertionError", OnFailureTest.class.getName()), log);
178         assertEquals(1, result.getFailureCount());
179     }
180 
181     public static class WatchmanTest {
182         private static String watchedLog;
183 
184         @Rule
185         public TestRule watcher = new TestWatcher() {
186             @Override
187             protected void failed(Throwable e, Description description) {
188                 watchedLog += description + " "
189                         + e.getClass().getSimpleName() + "\n";
190             }
191 
192             @Override
193             protected void succeeded(Description description) {
194                 watchedLog += description + " " + "success!\n";
195             }
196         };
197 
198         @Test
199         public void fails() {
200             fail();
201         }
202 
203         @Test
204         public void succeeds() {
205         }
206     }
207 
208     @Test
209     public void succeeded() {
210         WatchmanTest.watchedLog = "";
211         JUnitCore.runClasses(WatchmanTest.class);
212         assertThat(WatchmanTest.watchedLog, containsString(String.format("fails(%s) AssertionError", WatchmanTest.class.getName())));
213         assertThat(WatchmanTest.watchedLog, containsString(String.format("succeeds(%s) success!", WatchmanTest.class.getName())));
214     }
215 
216     public static class BeforesAndAfters {
217         private static StringBuilder watchedLog = new StringBuilder();
218 
219         @Before
220         public void before() {
221             watchedLog.append("before ");
222         }
223 
224         @Rule
225         public TestRule watcher = new LoggingTestWatcher(watchedLog);
226 
227         @After
228         public void after() {
229             watchedLog.append("after ");
230         }
231 
232         @Test
233         public void succeeds() {
234             watchedLog.append("test ");
235         }
236     }
237 
238     @Test
239     public void beforesAndAfters() {
240         BeforesAndAfters.watchedLog = new StringBuilder();
241         JUnitCore.runClasses(BeforesAndAfters.class);
242         assertThat(BeforesAndAfters.watchedLog.toString(),
243                 is("starting before test after succeeded finished "));
244     }
245 
246     public static class WrongTypedField {
247         @Rule
248         public int x = 5;
249 
250         @Test
251         public void foo() {
252         }
253     }
254 
255     @Test
256     public void validateWrongTypedField() {
257         assertThat(testResult(WrongTypedField.class),
258                 hasSingleFailureContaining("must implement MethodRule"));
259     }
260 
261     public static class SonOfWrongTypedField extends WrongTypedField {
262 
263     }
264 
265     @Test
266     public void validateWrongTypedFieldInSuperclass() {
267         assertThat(testResult(SonOfWrongTypedField.class),
268                 hasSingleFailureContaining("must implement MethodRule"));
269     }
270 
271     public static class PrivateRule {
272         @Rule
273         private TestRule rule = new TestName();
274 
275         @Test
276         public void foo() {
277         }
278     }
279 
280     @Test
281     public void validatePrivateRule() {
282         assertThat(testResult(PrivateRule.class),
283                 hasSingleFailureContaining("must be public"));
284     }
285 
286     public static class CustomTestName implements TestRule {
287         public String name = null;
288 
289         public Statement apply(final Statement base, final Description description) {
290             return new Statement() {
291                 @Override
292                 public void evaluate() throws Throwable {
293                     name = description.getMethodName();
294                     base.evaluate();
295                 }
296             };
297         }
298     }
299 
300     public static class UsesCustomMethodRule {
301         @Rule
302         public CustomTestName counter = new CustomTestName();
303 
304         @Test
305         public void foo() {
306             assertEquals("foo", counter.name);
307         }
308     }
309 
310     @Test
311     public void useCustomMethodRule() {
312         assertThat(testResult(UsesCustomMethodRule.class), isSuccessful());
313     }
314 
315     public static class MethodExampleTest {
316         private TestRule example = new TestRule() {
317             public Statement apply(final Statement base, Description description) {
318                 return new Statement() {
319                     @Override
320                     public void evaluate() throws Throwable {
321                         wasRun = true;
322                         base.evaluate();
323                     }
324 
325                     ;
326                 };
327             }
328         };
329 
330         @Rule
331         public TestRule getExample() {
332             return example;
333         }
334 
335         @Test
336         public void nothing() {
337 
338         }
339     }
340 
341     @Test
342     public void methodRuleIsIntroducedAndEvaluated() {
343         wasRun = false;
344         JUnitCore.runClasses(MethodExampleTest.class);
345         assertTrue(wasRun);
346     }
347 
348     public static class MethodBothKindsOfRule implements TestRule, org.junit.rules.MethodRule {
349         public int applications = 0;
350 
351         public Statement apply(Statement base, FrameworkMethod method,
352                 Object target) {
353             applications++;
354             return base;
355         }
356 
357         public Statement apply(Statement base, Description description) {
358             applications++;
359             return base;
360         }
361     }
362 
363     public static class MethodOneFieldTwoKindsOfRule {
364         private MethodBothKindsOfRule both = new MethodBothKindsOfRule();
365 
366         @Rule
367         public MethodBothKindsOfRule getBoth() {
368             return both;
369         }
370 
371         @Test
372         public void onlyOnce() {
373             assertEquals(1, both.applications);
374         }
375     }
376 
377 
378     @Test
379     public void methodOnlyApplyOnceEvenIfImplementsBothInterfaces() {
380         assertTrue(JUnitCore.runClasses(MethodOneFieldTwoKindsOfRule.class).wasSuccessful());
381     }
382 
383     public static class MethodSonOfExampleTest extends MethodExampleTest {
384 
385     }
386 
387     @Test
388     public void methodRuleIsIntroducedAndEvaluatedOnSubclass() {
389         wasRun = false;
390         JUnitCore.runClasses(MethodSonOfExampleTest.class);
391         assertTrue(wasRun);
392     }
393 
394 //	private static int runCount;
395 
396     public static class MethodMultipleRuleTest {
397         private static class Increment implements TestRule {
398             public Statement apply(final Statement base, Description description) {
399                 return new Statement() {
400                     @Override
401                     public void evaluate() throws Throwable {
402                         runCount++;
403                         base.evaluate();
404                     }
405 
406                     ;
407                 };
408             }
409         }
410 
411         private TestRule incrementor1 = new Increment();
412 
413         @Rule
414         public TestRule getIncrementor1() {
415             return incrementor1;
416         }
417 
418         private TestRule incrementor2 = new Increment();
419 
420         @Rule
421         public TestRule getIncrementor2() {
422             return incrementor2;
423         }
424 
425         @Test
426         public void nothing() {
427 
428         }
429     }
430 
431     @Test
432     public void methodMultipleRulesAreRun() {
433         runCount = 0;
434         JUnitCore.runClasses(MethodMultipleRuleTest.class);
435         assertEquals(2, runCount);
436     }
437 
438     public static class MethodNoRulesTest {
439         public int x;
440 
441         @Test
442         public void nothing() {
443 
444         }
445     }
446 
447     @Test
448     public void methodIgnoreNonRules() {
449         Result result = JUnitCore.runClasses(MethodNoRulesTest.class);
450         assertEquals(0, result.getFailureCount());
451     }
452 
453     public static class MethodOnFailureTest {
454         private TestRule watchman = new TestWatcher() {
455             @Override
456             protected void failed(Throwable e, Description description) {
457                 log += description + " " + e.getClass().getSimpleName();
458             }
459         };
460 
461         @Rule
462         public TestRule getWatchman() {
463             return watchman;
464         }
465 
466         @Test
467         public void nothing() {
468             fail();
469         }
470     }
471 
472     @Test
473     public void methodOnFailure() {
474         log = "";
475         Result result = JUnitCore.runClasses(MethodOnFailureTest.class);
476         assertEquals(String.format("nothing(%s) AssertionError", MethodOnFailureTest.class.getName()), log);
477         assertEquals(1, result.getFailureCount());
478     }
479 
480     public static class MethodOnSkippedTest {
481         private TestRule watchman = new TestWatcher() {
482             @Override
483             protected void skipped(AssumptionViolatedException e, Description description) {
484                 log += description + " " + e.getClass().getSimpleName();
485             }
486         };
487 
488         @Rule
489         public TestRule getWatchman() {
490             return watchman;
491         }
492 
493         @Test
494         public void nothing() {
495             Assume.assumeTrue(false);
496         }
497     }
498 
499     @Test
500     public void methodOnSkipped() {
501         log = "";
502         Result result = JUnitCore.runClasses(MethodOnSkippedTest.class);
503         assertEquals(String.format("nothing(%s) AssumptionViolatedException", MethodOnSkippedTest.class.getName()), log);
504         assertEquals(0, result.getFailureCount());
505         assertEquals(1, result.getRunCount());
506     }
507 
508     public static class MethodWatchmanTest {
509         @SuppressWarnings("unused")
510         private static String watchedLog;
511 
512         private TestRule watchman = new TestWatcher() {
513             @Override
514             protected void failed(Throwable e, Description description) {
515                 watchedLog += description + " "
516                         + e.getClass().getSimpleName() + "\n";
517             }
518 
519             @Override
520             protected void succeeded(Description description) {
521                 watchedLog += description + " " + "success!\n";
522             }
523         };
524 
525         @Rule
526         public TestRule getWatchman() {
527             return watchman;
528         }
529 
530         @Test
531         public void fails() {
532             fail();
533         }
534 
535         @Test
536         public void succeeds() {
537         }
538     }
539 
540     @Test
541     public void methodSucceeded() {
542         WatchmanTest.watchedLog = "";
543         JUnitCore.runClasses(WatchmanTest.class);
544         assertThat(WatchmanTest.watchedLog, containsString(String.format("fails(%s) AssertionError", WatchmanTest.class.getName())));
545         assertThat(WatchmanTest.watchedLog, containsString(String.format("succeeds(%s) success!", WatchmanTest.class.getName())));
546     }
547 
548     public static class MethodBeforesAndAfters {
549         private static String watchedLog;
550 
551         @Before
552         public void before() {
553             watchedLog += "before ";
554         }
555 
556         private TestRule watchman = new TestWatcher() {
557             @Override
558             protected void starting(Description d) {
559                 watchedLog += "starting ";
560             }
561 
562             @Override
563             protected void finished(Description d) {
564                 watchedLog += "finished ";
565             }
566 
567             @Override
568             protected void succeeded(Description d) {
569                 watchedLog += "succeeded ";
570             }
571         };
572 
573         @Rule
574         public TestRule getWatchman() {
575             return watchman;
576         }
577 
578         @After
579         public void after() {
580             watchedLog += "after ";
581         }
582 
583         @Test
584         public void succeeds() {
585             watchedLog += "test ";
586         }
587     }
588 
589     @Test
590     public void methodBeforesAndAfters() {
591         MethodBeforesAndAfters.watchedLog = "";
592         JUnitCore.runClasses(MethodBeforesAndAfters.class);
593         assertThat(MethodBeforesAndAfters.watchedLog, is("starting before test after succeeded finished "));
594     }
595 
596     public static class MethodWrongTypedField {
597         @Rule
598         public int getX() {
599             return 5;
600         }
601 
602         @Test
603         public void foo() {
604         }
605     }
606 
607     @Test
608     public void methodValidateWrongTypedField() {
609         assertThat(testResult(MethodWrongTypedField.class),
610                 hasSingleFailureContaining("must return an implementation of MethodRule"));
611     }
612 
613     public static class MethodSonOfWrongTypedField extends MethodWrongTypedField {
614 
615     }
616 
617     @Test
618     public void methodValidateWrongTypedFieldInSuperclass() {
619         assertThat(testResult(MethodSonOfWrongTypedField.class),
620                 hasSingleFailureContaining("must return an implementation of MethodRule"));
621     }
622 
623     public static class MethodPrivateRule {
624         @Rule
625         private TestRule getRule() {
626             return new TestName();
627         }
628 
629         @Test
630         public void foo() {
631         }
632     }
633 
634     @Test
635     public void methodValidatePrivateRule() {
636         assertThat(testResult(MethodPrivateRule.class),
637                 hasSingleFailureContaining("must be public"));
638     }
639 
640     public static class MethodUsesCustomMethodRule {
641         private CustomTestName counter = new CustomTestName();
642 
643         @Rule
644         public CustomTestName getCounter() {
645             return counter;
646         }
647 
648         @Test
649         public void foo() {
650             assertEquals("foo", counter.name);
651         }
652     }
653 
654     @Test
655     public void methodUseCustomMethodRule() {
656         assertThat(testResult(MethodUsesCustomMethodRule.class), isSuccessful());
657     }
658 
659     private static final List<String> orderList = new LinkedList<String>();
660 
661     private static class OrderTestRule implements TestRule {
662         private String name;
663 
664         public OrderTestRule(String name) {
665             this.name = name;
666         }
667 
668         public Statement apply(final Statement base, final Description description) {
669             return new Statement() {
670                 @Override
671                 public void evaluate() throws Throwable {
672                     orderList.add(name);
673                     base.evaluate();
674                 }
675             };
676         }
677     }
678 
679     ;
680 
681     public static class UsesFieldAndMethodRule {
682         @Rule
683         public OrderTestRule orderMethod() {
684             return new OrderTestRule("orderMethod");
685         }
686 
687         @Rule
688         public OrderTestRule orderField = new OrderTestRule("orderField");
689 
690         @Test
691         public void foo() {
692             assertEquals("orderField", orderList.get(0));
693             assertEquals("orderMethod", orderList.get(1));
694         }
695     }
696 
697     @Test
698     public void usesFieldAndMethodRule() {
699         orderList.clear();
700         assertThat(testResult(UsesFieldAndMethodRule.class), isSuccessful());
701     }
702 
703     public static class MultipleCallsTest implements TestRule {
704         public int applications = 0;
705 
706         public Statement apply(Statement base, Description description) {
707             applications++;
708             return base;
709         }
710     }
711 
712     public static class CallMethodOnlyOnceRule {
713         int countOfMethodCalls = 0;
714 
715         private static class Dummy implements TestRule {
716             public Statement apply(final Statement base, Description description) {
717                 return new Statement() {
718                     @Override
719                     public void evaluate() throws Throwable {
720                         base.evaluate();
721                     }
722 
723                     ;
724                 };
725             }
726         }
727 
728         @Rule
729         public Dummy both() {
730             countOfMethodCalls++;
731             return new Dummy();
732         }
733 
734         @Test
735         public void onlyOnce() {
736             assertEquals(1, countOfMethodCalls);
737         }
738     }
739 
740     @Test
741     public void testCallMethodOnlyOnceRule() {
742         assertTrue(JUnitCore.runClasses(CallMethodOnlyOnceRule.class).wasSuccessful());
743     }
744 }