package org.junit.tests.experimental.rules; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.experimental.results.PrintableResult.testResult; import static org.junit.experimental.results.ResultMatchers.hasSingleFailureContaining; import static org.junit.experimental.results.ResultMatchers.isSuccessful; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.MethodRule; import org.junit.rules.TestName; import org.junit.rules.TestRule; import org.junit.rules.TestWatchman; import org.junit.runner.Description; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; @SuppressWarnings("deprecation") public class MethodRulesTest { private static boolean wasRun; public static class ExampleTest { @Rule public MethodRule example = new MethodRule() { public Statement apply(final Statement base, FrameworkMethod method, Object target) { return new Statement() { @Override public void evaluate() throws Throwable { wasRun = true; base.evaluate(); } ; }; } }; @Test public void nothing() { } } @Test public void ruleIsIntroducedAndEvaluated() { wasRun = false; JUnitCore.runClasses(ExampleTest.class); assertTrue(wasRun); } public static class SonOfExampleTest extends ExampleTest { } @Test public void ruleIsIntroducedAndEvaluatedOnSubclass() { wasRun = false; JUnitCore.runClasses(SonOfExampleTest.class); assertTrue(wasRun); } private static int runCount; public static class MultipleRuleTest { private static class Increment implements MethodRule { public Statement apply(final Statement base, FrameworkMethod method, Object target) { return new Statement() { @Override public void evaluate() throws Throwable { runCount++; base.evaluate(); } ; }; } } @Rule public MethodRule incrementor1 = new Increment(); @Rule public MethodRule incrementor2 = new Increment(); @Test public void nothing() { } } @Test public void multipleRulesAreRun() { runCount = 0; JUnitCore.runClasses(MultipleRuleTest.class); assertEquals(2, runCount); } public static class NoRulesTest { public int x; @Test public void nothing() { } } @Test public void ignoreNonRules() { Result result = JUnitCore.runClasses(NoRulesTest.class); assertEquals(0, result.getFailureCount()); } private static String log; public static class OnFailureTest { @Rule public MethodRule watchman = new TestWatchman() { @Override public void failed(Throwable e, FrameworkMethod method) { log += method.getName() + " " + e.getClass().getSimpleName(); } }; @Test public void nothing() { fail(); } } @Test public void onFailure() { log = ""; Result result = JUnitCore.runClasses(OnFailureTest.class); assertEquals("nothing AssertionError", log); assertEquals(1, result.getFailureCount()); } public static class WatchmanTest { private static String watchedLog; @Rule public MethodRule watchman = new TestWatchman() { @Override public void failed(Throwable e, FrameworkMethod method) { watchedLog += method.getName() + " " + e.getClass().getSimpleName() + "\n"; } @Override public void succeeded(FrameworkMethod method) { watchedLog += method.getName() + " " + "success!\n"; } }; @Test public void fails() { fail(); } @Test public void succeeds() { } } @Test public void succeeded() { WatchmanTest.watchedLog = ""; JUnitCore.runClasses(WatchmanTest.class); assertThat(WatchmanTest.watchedLog, containsString("fails AssertionError")); assertThat(WatchmanTest.watchedLog, containsString("succeeds success!")); } public static class BeforesAndAfters { private static String watchedLog; @Before public void before() { watchedLog += "before "; } @Rule public MethodRule watchman = new TestWatchman() { @Override public void starting(FrameworkMethod method) { watchedLog += "starting "; } @Override public void finished(FrameworkMethod method) { watchedLog += "finished "; } @Override public void succeeded(FrameworkMethod method) { watchedLog += "succeeded "; } }; @After public void after() { watchedLog += "after "; } @Test public void succeeds() { watchedLog += "test "; } } @Test public void beforesAndAfters() { BeforesAndAfters.watchedLog = ""; JUnitCore.runClasses(BeforesAndAfters.class); assertThat(BeforesAndAfters.watchedLog, is("starting before test after succeeded finished ")); } public static class WrongTypedField { @Rule public int x = 5; @Test public void foo() { } } @Test public void validateWrongTypedField() { assertThat(testResult(WrongTypedField.class), hasSingleFailureContaining("must implement MethodRule")); } public static class SonOfWrongTypedField extends WrongTypedField { } @Test public void validateWrongTypedFieldInSuperclass() { assertThat(testResult(SonOfWrongTypedField.class), hasSingleFailureContaining("must implement MethodRule")); } public static class PrivateRule { @Rule private TestRule rule = new TestName(); @Test public void foo() { } } @Test public void validatePrivateRule() { assertThat(testResult(PrivateRule.class), hasSingleFailureContaining("must be public")); } public static class CustomTestName implements TestRule { public String name = null; public Statement apply(final Statement base, final Description description) { return new Statement() { @Override public void evaluate() throws Throwable { name = description.getMethodName(); base.evaluate(); } }; } } public static class UsesCustomMethodRule { @Rule public CustomTestName counter = new CustomTestName(); @Test public void foo() { assertEquals("foo", counter.name); } } @Test public void useCustomMethodRule() { assertThat(testResult(UsesCustomMethodRule.class), isSuccessful()); } }