diff --git a/src/main/java/org/junit/rules/ExpectedException.java b/src/main/java/org/junit/rules/ExpectedException.java index bac2fba2e1e1..8852341ad252 100644 --- a/src/main/java/org/junit/rules/ExpectedException.java +++ b/src/main/java/org/junit/rules/ExpectedException.java @@ -1,17 +1,18 @@ package org.junit.rules; import static org.hamcrest.CoreMatchers.instanceOf; +import static org.junit.Assert.assertThat; import static org.junit.matchers.JUnitMatchers.both; import static org.junit.matchers.JUnitMatchers.containsString; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.StringDescription; -import org.junit.Assert; +import org.junit.internal.AssumptionViolatedException; import org.junit.internal.matchers.TypeSafeMatcher; import org.junit.runners.model.Statement; /** - * The ExpectedException Rule allows in-test specification of expected exception + * The ExpectedException rule allows in-test specification of expected exception * types and messages: * *
@@ -22,7 +23,7 @@
  * 
  * 	@Test
  * 	public void throwsNothing() {
- *    // no exception expected, none thrown: passes.
+ * 		// no exception expected, none thrown: passes.
  * 	}
  * 
  * 	@Test
@@ -40,11 +41,39 @@
  * 	}
  * }
  * 
+ * + * By default ExpectedException rule doesn't handle AssertionErrors and + * AssumptionViolatedExceptions, because such exceptions are used by JUnit. If + * you want to handle such exceptions you have to call @link + * {@link #handleAssertionErrors()} or @link + * {@link #handleAssumptionViolatedExceptions()}. + * + *
+ * // These tests all pass.
+ * public static class HasExpectedException {
+ * 	@Rule
+ * 	public ExpectedException thrown= ExpectedException.none();
+ * 
+ * 	@Test
+ * 	public void throwExpectedAssertionError() {
+ * 		thrown.handleAssertionErrors();
+ * 		thrown.expect(AssertionError.class);
+ * 		throw new AssertionError();
+ * 	}
+ * 
+ * 	@Test
+ * 	public void throwExpectAssumptionViolatedException() {
+ * 		thrown.handleAssumptionViolatedExceptions();
+ * 		thrown.expect(AssumptionViolatedException.class);
+ * 		throw new AssumptionViolatedException("");
+ * 	}
+ * }
+ * 
*/ public class ExpectedException implements TestRule { /** - * @return a Rule that expects no exception to be thrown - * (identical to behavior without this Rule) + * @return a Rule that expects no exception to be thrown (identical to + * behavior without this Rule) */ public static ExpectedException none() { return new ExpectedException(); @@ -52,19 +81,32 @@ public static ExpectedException none() { private Matcher fMatcher= null; + private boolean handleAssumptionViolatedExceptions= false; + + private boolean handleAssertionErrors= false; + private ExpectedException() { - } - + + public void handleAssertionErrors() { + handleAssertionErrors= true; + } + + public void handleAssumptionViolatedExceptions() { + handleAssumptionViolatedExceptions= true; + } + public Statement apply(Statement base, org.junit.runner.Description description) { return new ExpectedExceptionStatement(base); } /** - * Adds {@code matcher} to the list of requirements for any thrown exception. + * Adds {@code matcher} to the list of requirements for any thrown + * exception. */ - // Should be able to remove this suppression in some brave new hamcrest world. + // Should be able to remove this suppression in some brave new hamcrest + // world. @SuppressWarnings("unchecked") public void expect(Matcher matcher) { if (fMatcher == null) @@ -74,24 +116,24 @@ public void expect(Matcher matcher) { } /** - * Adds to the list of requirements for any thrown exception that it - * should be an instance of {@code type} + * Adds to the list of requirements for any thrown exception that it should + * be an instance of {@code type} */ public void expect(Class type) { expect(instanceOf(type)); } /** - * Adds to the list of requirements for any thrown exception that it - * should contain string {@code substring} + * Adds to the list of requirements for any thrown exception that it should + * contain string {@code substring} */ public void expectMessage(String substring) { expectMessage(containsString(substring)); } /** - * Adds {@code matcher} to the list of requirements for the message - * returned from any thrown exception. + * Adds {@code matcher} to the list of requirements for the message returned + * from any thrown exception. */ public void expectMessage(Matcher matcher) { expect(hasMessage(matcher)); @@ -108,10 +150,14 @@ public ExpectedExceptionStatement(Statement base) { public void evaluate() throws Throwable { try { fNext.evaluate(); + } catch (AssumptionViolatedException e) { + optionallyHandleException(e, handleAssumptionViolatedExceptions); + return; + } catch (AssertionError e) { + optionallyHandleException(e, handleAssertionErrors); + return; } catch (Throwable e) { - if (fMatcher == null) - throw e; - Assert.assertThat(e, fMatcher); + handleException(e); return; } if (fMatcher != null) @@ -120,17 +166,32 @@ public void evaluate() throws Throwable { } } + private void optionallyHandleException(Throwable e, boolean handleException) + throws Throwable { + if (handleException) + handleException(e); + else + throw e; + + } + + private void handleException(Throwable e) throws Throwable { + if (fMatcher == null) + throw e; + assertThat(e, fMatcher); + } + private Matcher hasMessage(final Matcher matcher) { return new TypeSafeMatcher() { public void describeTo(Description description) { description.appendText("exception with message "); description.appendDescriptionOf(matcher); } - + @Override public boolean matchesSafely(Throwable item) { return matcher.matches(item.getMessage()); } }; } -} +} \ No newline at end of file diff --git a/src/main/java/org/junit/runner/notification/EventCollector.java b/src/main/java/org/junit/runner/notification/EventCollector.java new file mode 100644 index 000000000000..8fd3fe9089e7 --- /dev/null +++ b/src/main/java/org/junit/runner/notification/EventCollector.java @@ -0,0 +1,58 @@ +package org.junit.runner.notification; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.runner.Description; +import org.junit.runner.Result; + +public class EventCollector extends RunListener { + private final List testRunsStarted= new ArrayList(); + + private final List testRunsFinished= new ArrayList(); + + private final List testsStarted= new ArrayList(); + + private final List testsFinished= new ArrayList(); + + private final List failures= new ArrayList(); + + private final List violatedAssumptions= new ArrayList(); + + private final List testsIgnored= new ArrayList(); + + @Override + public void testRunStarted(Description description) throws Exception { + testRunsStarted.add(description); + } + + @Override + public void testRunFinished(Result result) throws Exception { + testRunsFinished.add(result); + } + + @Override + public void testStarted(Description description) throws Exception { + testsStarted.add(description); + } + + @Override + public void testFinished(Description description) throws Exception { + testsFinished.add(description); + } + + @Override + public void testFailure(Failure failure) throws Exception { + failures.add(failure); + } + + @Override + public void testAssumptionFailure(Failure failure) { + violatedAssumptions.add(failure); + } + + @Override + public void testIgnored(Description description) throws Exception { + testsIgnored.add(description); + } +} diff --git a/src/test/java/org/junit/tests/AllTests.java b/src/test/java/org/junit/tests/AllTests.java index bca56f309bdb..9ce23d06d190 100644 --- a/src/test/java/org/junit/tests/AllTests.java +++ b/src/test/java/org/junit/tests/AllTests.java @@ -25,7 +25,7 @@ import org.junit.tests.experimental.parallel.ParallelMethodTest; import org.junit.tests.experimental.rules.BlockJUnit4ClassRunnerOverrideTest; import org.junit.tests.experimental.rules.ClassRulesTest; -import org.junit.tests.experimental.rules.ExpectedExceptionRuleTest; +import org.junit.tests.experimental.rules.ExpectedExceptionTest; import org.junit.tests.experimental.rules.ExternalResourceRuleTest; import org.junit.tests.experimental.rules.MethodRulesTest; import org.junit.tests.experimental.rules.NameRulesTest; @@ -144,7 +144,7 @@ ParentRunnerTest.class, NameRulesTest.class, ClassRulesTest.class, - ExpectedExceptionRuleTest.class, + ExpectedExceptionTest.class, TempFolderRuleTest.class, ExternalResourceRuleTest.class, VerifierRuleTest.class, diff --git a/src/test/java/org/junit/tests/experimental/rules/EventCollector.java b/src/test/java/org/junit/tests/experimental/rules/EventCollector.java new file mode 100644 index 000000000000..14db70dcb640 --- /dev/null +++ b/src/test/java/org/junit/tests/experimental/rules/EventCollector.java @@ -0,0 +1,157 @@ +package org.junit.tests.experimental.rules; + +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.matchers.JUnitMatchers.both; + +import java.util.ArrayList; +import java.util.List; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Matcher; +import org.junit.runner.Description; +import org.junit.runner.Result; +import org.junit.runner.notification.Failure; +import org.junit.runner.notification.RunListener; + +class EventCollector extends RunListener { + private final List testRunsStarted= new ArrayList(); + + private final List testRunsFinished= new ArrayList(); + + private final List testsStarted= new ArrayList(); + + private final List testsFinished= new ArrayList(); + + private final List failures= new ArrayList(); + + private final List assumptionFailures= new ArrayList(); + + private final List testIgnored= new ArrayList(); + + @Override + public void testRunStarted(Description description) throws Exception { + testRunsStarted.add(description); + } + + @Override + public void testRunFinished(Result result) throws Exception { + testRunsFinished.add(result); + } + + @Override + public void testStarted(Description description) throws Exception { + testsStarted.add(description); + } + + @Override + public void testFinished(Description description) throws Exception { + testsFinished.add(description); + } + + @Override + public void testFailure(Failure failure) throws Exception { + failures.add(failure); + } + + @Override + public void testAssumptionFailure(Failure failure) { + assumptionFailures.add(failure); + } + + @Override + public void testIgnored(Description description) throws Exception { + testIgnored.add(description); + } + + @Override + public String toString() { + StringBuilder sb= new StringBuilder(); + sb.append(testRunsStarted.size()); + sb.append(" test runs started, "); + sb.append(testRunsFinished.size()); + sb.append(" test runs finished, "); + sb.append(testsStarted.size()); + sb.append(" tests started, "); + sb.append(testsFinished.size()); + sb.append(" tests finished, "); + sb.append(failures.size()); + sb.append(" failures, "); + sb.append(assumptionFailures.size()); + sb.append(" assumption failures, "); + sb.append(testIgnored.size()); + sb.append(" tests ignored"); + + return sb.toString(); + } + + static Matcher everyTestRunSuccessful() { + return both(hasNoFailure()).and(hasNoAssumptionFailure()); + } + + private static Matcher hasNumberOfFailures( + final int numberOfFailures) { + return new BaseMatcher() { + public boolean matches(Object item) { + return ((EventCollector) item).failures.size() == numberOfFailures; + } + + public void describeTo(org.hamcrest.Description description) { + description.appendText("has "); + description.appendValue(numberOfFailures); + description.appendText(" failures"); + } + }; + } + + static Matcher hasSingleFailure() { + return hasNumberOfFailures(1); + } + + static Matcher hasNoFailure() { + return hasNumberOfFailures(0); + } + + private static Matcher hasNumberOfAssumptionFailures( + final int numberOfFailures) { + return new BaseMatcher() { + public boolean matches(Object item) { + return ((EventCollector) item).assumptionFailures.size() == numberOfFailures; + } + + public void describeTo(org.hamcrest.Description description) { + description.appendText("has "); + description.appendValue(numberOfFailures); + description.appendText(" assumption failures"); + } + }; + } + + static Matcher hasSingleAssumptionFailure() { + return hasNumberOfAssumptionFailures(1); + } + + static Matcher hasNoAssumptionFailure() { + return hasNumberOfAssumptionFailures(0); + } + + static Matcher hasSingleFailureWithMessage(String message) { + return hasSingleFailureWithMessage(equalTo(message)); + } + + static Matcher hasSingleFailureWithMessage( + final Matcher messageMatcher) { + return new BaseMatcher() { + public boolean matches(Object item) { + return hasSingleFailure().matches(item) + && messageMatcher + .matches(((EventCollector) item).failures + .get(0).getMessage()); + } + + public void describeTo(org.hamcrest.Description description) { + description.appendText("has single failure with message "); + messageMatcher.describeTo(description); + } + }; + } +} diff --git a/src/test/java/org/junit/tests/experimental/rules/ExpectedExceptionRuleTest.java b/src/test/java/org/junit/tests/experimental/rules/ExpectedExceptionRuleTest.java deleted file mode 100644 index b5119cd4adca..000000000000 --- a/src/test/java/org/junit/tests/experimental/rules/ExpectedExceptionRuleTest.java +++ /dev/null @@ -1,232 +0,0 @@ -package org.junit.tests.experimental.rules; - -import static org.hamcrest.CoreMatchers.any; -import static org.junit.Assert.assertThat; -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 static org.junit.matchers.JUnitMatchers.both; -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.junit.Rule; -import org.junit.Test; -import org.junit.internal.matchers.TypeSafeMatcher; -import org.junit.rules.ExpectedException; - -public class ExpectedExceptionRuleTest { - public static class HasExpectedException { - @Rule - public ExpectedException thrown= ExpectedException.none(); - - @Test - public void throwsNothing() { - - } - - @Test - public void throwsNullPointerException() { - thrown.expect(NullPointerException.class); - throw new NullPointerException(); - } - - @Test - public void throwsNullPointerExceptionWithMessage() { - thrown.expect(NullPointerException.class); - thrown.expectMessage("happened?"); - throw new NullPointerException("What happened?"); - } - } - - @Test - public void expectedExceptionPasses() { - assertThat(testResult(HasExpectedException.class), isSuccessful()); - } - - public static class HasWrongExpectedException { - @Rule - public ExpectedException thrown= ExpectedException.none(); - - @Test - public void throwsNullPointerException() { - thrown.expect(NullPointerException.class); - throw new IllegalArgumentException(); - } - } - - @Test - public void unExpectedExceptionFails() { - assertThat( - testResult(HasWrongExpectedException.class), - hasSingleFailureContaining("Expected: an instance of java.lang.NullPointerException")); - } - - public static class HasWrongMessage { - @Rule - public ExpectedException thrown= ExpectedException.none(); - - @Test - public void throwsNullPointerException() { - thrown.expectMessage("expectedMessage"); - throw new IllegalArgumentException("actualMessage"); - } - } - - @Test - public void wrongMessageFails() { - assertThat( - testResult(HasWrongMessage.class), both( - hasSingleFailureContaining("expectedMessage")).and( - hasSingleFailureContaining("actualMessage"))); - } - - public static class WronglyExpectsException { - @Rule - public ExpectedException thrown= ExpectedException.none(); - - @Test - public void doesntThrowNullPointerException() { - thrown.expect(NullPointerException.class); - } - } - - @Test - public void failsIfExceptionNeverComes() { - assertThat( - testResult(WronglyExpectsException.class), - hasSingleFailureContaining("Expected test to throw an instance of java.lang.NullPointerException")); - } - - public static class WronglyExpectsExceptionMessage { - @Rule - public ExpectedException thrown= ExpectedException.none(); - - @Test - public void doesntThrowAnything() { - thrown.expectMessage("anything!"); - } - } - - @Test - public void failsIfExceptionMessageNeverComes() { - assertThat( - testResult(WronglyExpectsExceptionMessage.class), - hasSingleFailureContaining("Expected test to throw exception with message a string containing \"anything!\"")); - } - - public static class ExpectsSubstring { - @Rule - public ExpectedException thrown= ExpectedException.none(); - - @Test - public void throwsMore() { - thrown.expectMessage("anything!"); - throw new NullPointerException( - "This could throw anything! (as long as it has the right substring)"); - } - } - - @Test - public void passesWithSubstringMethod() { - assertThat(testResult(ExpectsSubstring.class), isSuccessful()); - } - - public static class ExpectsSubstringNullMessage { - @Rule - public ExpectedException thrown= ExpectedException.none(); - - @Test - public void throwsMore() { - thrown.expectMessage("anything!"); - throw new NullPointerException(); - } - } - - @Test - public void failsWithNullExceptionMessage() { - assertThat(testResult(ExpectsSubstringNullMessage.class), - hasSingleFailureContaining("NullPointerException")); - } - - public static class ExpectsMessageMatcher { - @Rule - public ExpectedException thrown= ExpectedException.none(); - - @Test - public void throwsMore() { - thrown.expectMessage(startsWith("Ack")); - throw new NullPointerException("Ack!"); - } - } - - @Test - public void succeedsWithMessageMatcher() { - assertThat(testResult(ExpectsMessageMatcher.class), isSuccessful()); - } - - public static class ExpectedMessageMatcherFails { - @Rule - public ExpectedException thrown= ExpectedException.none(); - - @Test - public void throwsMore() { - thrown.expectMessage(startsWith("Wrong start")); - throw new NullPointerException("Back!"); - } - } - - - - private static Matcher startsWith(final String prefix) { - return new TypeSafeMatcher() { - public void describeTo(Description description) { - description.appendText("starts with "); - description.appendText(prefix); - } - - @Override - public boolean matchesSafely(String item) { - return item.startsWith(prefix); - } - }; - } - - @Test - public void failsWithMatcher() { - assertThat(testResult(ExpectedMessageMatcherFails.class), - hasSingleFailureContaining("Wrong start")); - } - - public static class ExpectsMatcher { - @Rule - public ExpectedException thrown= ExpectedException.none(); - - @Test - public void throwsMore() { - thrown.expect(any(Throwable.class)); - throw new NullPointerException("Ack!"); - } - } - - @Test - public void succeedsWithMatcher() { - assertThat(testResult(ExpectsMatcher.class), isSuccessful()); - } - - public static class ExpectsMultipleMatchers { - @Rule - public ExpectedException thrown= ExpectedException.none(); - - @Test - public void throwsMore() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Ack!"); - throw new NullPointerException("Ack!"); - } - } - - @Test - public void failsWithMultipleMatchers() { - assertThat(testResult(ExpectsMultipleMatchers.class), - hasSingleFailureContaining("IllegalArgumentException")); - } -} diff --git a/src/test/java/org/junit/tests/experimental/rules/ExpectedExceptionTest.java b/src/test/java/org/junit/tests/experimental/rules/ExpectedExceptionTest.java new file mode 100644 index 000000000000..fbff4523eea1 --- /dev/null +++ b/src/test/java/org/junit/tests/experimental/rules/ExpectedExceptionTest.java @@ -0,0 +1,324 @@ +package org.junit.tests.experimental.rules; + +import static java.util.Arrays.asList; +import static org.hamcrest.CoreMatchers.any; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; +import static org.junit.rules.ExpectedException.none; +import static org.junit.tests.experimental.rules.EventCollector.everyTestRunSuccessful; +import static org.junit.tests.experimental.rules.EventCollector.hasSingleAssumptionFailure; +import static org.junit.tests.experimental.rules.EventCollector.hasSingleFailure; +import static org.junit.tests.experimental.rules.EventCollector.hasSingleFailureWithMessage; + +import java.io.IOException; +import java.util.Collection; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.junit.Rule; +import org.junit.Test; +import org.junit.internal.AssumptionViolatedException; +import org.junit.internal.matchers.TypeSafeMatcher; +import org.junit.rules.ExpectedException; +import org.junit.runner.JUnitCore; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +@RunWith(Parameterized.class) +public class ExpectedExceptionTest { + private static final String ARBITRARY_MESSAGE= "arbitrary message"; + + @Parameters + public static Collection testsWithEventMatcher() { + return asList(new Object[][] { + { EmptyTestExpectingNoException.class, everyTestRunSuccessful() }, + { ThrowExceptionWithExpectedType.class, + everyTestRunSuccessful() }, + { ThrowExceptionWithExpectedPartOfMessage.class, + everyTestRunSuccessful() }, + { + ThrowExceptionWithWrongType.class, + hasSingleFailureWithMessage(startsWith("\nExpected: an instance of java.lang.NullPointerException")) }, + { + HasWrongMessage.class, + hasSingleFailureWithMessage("\nExpected: exception with message a string containing \"expectedMessage\"\n" + + " got: \n") }, + { + ThrowNoExceptionButExpectExceptionWithType.class, + hasSingleFailureWithMessage("Expected test to throw an instance of java.lang.NullPointerException") }, + { WronglyExpectsExceptionMessage.class, hasSingleFailure() }, + { ExpectsSubstring.class, everyTestRunSuccessful() }, + { + ExpectsSubstringNullMessage.class, + hasSingleFailureWithMessage(startsWith("\nExpected: exception with message a string containing \"anything!\"")) }, + { ExpectsMessageMatcher.class, everyTestRunSuccessful() }, + { + ExpectedMessageMatcherFails.class, + hasSingleFailureWithMessage(startsWith("\nExpected: exception with message \"Wrong start\"")) }, + { ExpectsMatcher.class, everyTestRunSuccessful() }, + { ThrowExpectedAssumptionViolatedException.class, + everyTestRunSuccessful() }, + { ThrowAssumptionViolatedExceptionButExpectOtherType.class, + hasSingleFailure() }, + { ViolateAssumptionAndExpectException.class, + hasSingleAssumptionFailure() }, + { ThrowExpectedAssertionError.class, everyTestRunSuccessful() }, + { + ThrowUnexpectedAssertionError.class, + hasSingleFailureWithMessage(startsWith("\nExpected: an instance of java.lang.NullPointerException")) }, + { FailAndDontHandleAssertinErrors.class, + hasSingleFailureWithMessage(ARBITRARY_MESSAGE) }, + { + ExpectsMultipleMatchers.class, + hasSingleFailureWithMessage(startsWith("\nExpected: (exception with message a string containing \"Ack!\" and an instance of java.lang.IllegalArgumentException)")) } }); + } + + private final Class classUnderTest; + + private final Matcher matcher; + + public ExpectedExceptionTest(Class classUnderTest, + Matcher matcher) { + this.classUnderTest= classUnderTest; + this.matcher= matcher; + } + + @Test + public void runTestAndVerifyResult() { + EventCollector collector= new EventCollector(); + JUnitCore core= new JUnitCore(); + core.addListener(collector); + core.run(classUnderTest); + assertThat(collector, matcher); + } + + public static class EmptyTestExpectingNoException { + @Rule + public ExpectedException thrown= none(); + + @Test + public void throwsNothing() { + } + } + + public static class ThrowExceptionWithExpectedType { + @Rule + public ExpectedException thrown= none(); + + @Test + public void throwsNullPointerException() { + thrown.expect(NullPointerException.class); + throw new NullPointerException(); + } + } + + public static class ThrowExceptionWithExpectedPartOfMessage { + @Rule + public ExpectedException thrown= none(); + + @Test + public void throwsNullPointerExceptionWithMessage() { + thrown.expect(NullPointerException.class); + thrown.expectMessage(ARBITRARY_MESSAGE); + throw new NullPointerException(ARBITRARY_MESSAGE + "something else"); + } + } + + public static class ThrowExceptionWithWrongType { + @Rule + public ExpectedException thrown= none(); + + @Test + public void throwsNullPointerException() { + thrown.expect(NullPointerException.class); + throw new IllegalArgumentException(); + } + } + + public static class HasWrongMessage { + @Rule + public ExpectedException thrown= none(); + + @Test + public void throwsNullPointerException() { + thrown.expectMessage("expectedMessage"); + throw new IllegalArgumentException("actualMessage"); + } + } + + public static class ThrowNoExceptionButExpectExceptionWithType { + @Rule + public ExpectedException thrown= none(); + + @Test + public void doesntThrowNullPointerException() { + thrown.expect(NullPointerException.class); + } + } + + public static class WronglyExpectsExceptionMessage { + @Rule + public ExpectedException thrown= none(); + + @Test + public void doesntThrowAnything() { + thrown.expectMessage("anything!"); + } + } + + public static class ExpectsSubstring { + @Rule + public ExpectedException thrown= none(); + + @Test + public void throwsMore() { + thrown.expectMessage("anything!"); + throw new NullPointerException( + "This could throw anything! (as long as it has the right substring)"); + } + } + + public static class ExpectsSubstringNullMessage { + @Rule + public ExpectedException thrown= none(); + + @Test + public void throwsMore() { + thrown.expectMessage("anything!"); + throw new NullPointerException(); + } + } + + public static class ExpectsMessageMatcher { + @Rule + public ExpectedException thrown= none(); + + @Test + public void throwsMore() { + thrown.expectMessage(startsWith(ARBITRARY_MESSAGE)); + throw new NullPointerException(ARBITRARY_MESSAGE + "!"); + } + } + + public static class ExpectedMessageMatcherFails { + @Rule + public ExpectedException thrown= none(); + + @Test + public void throwsMore() { + thrown.expectMessage(equalTo("Wrong start")); + throw new NullPointerException("Back!"); + } + } + + public static class ExpectsMatcher { + @Rule + public ExpectedException thrown= none(); + + @Test + public void throwsMore() { + thrown.expect(any(IOException.class)); + throw new NullPointerException("Ack!"); + } + } + + public static class ExpectsMultipleMatchers { + @Rule + public ExpectedException thrown= none(); + + @Test + public void throwsMore() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Ack!"); + throw new NullPointerException("Ack!"); + } + } + + public static class FailAndDontHandleAssertinErrors { + @Rule + public ExpectedException thrown= none(); + + @Test + public void violatedAssumption() { + thrown.expect(IllegalArgumentException.class); + fail(ARBITRARY_MESSAGE); + } + } + + public static class ThrowUnexpectedAssertionError { + @Rule + public ExpectedException thrown= none(); + + @Test + public void wrongException() { + thrown.handleAssertionErrors(); + thrown.expect(NullPointerException.class); + throw new AssertionError("the unexpected assertion error"); + } + } + + public static class ThrowExpectedAssertionError { + @Rule + public ExpectedException thrown= none(); + + @Test + public void wrongException() { + thrown.handleAssertionErrors(); + thrown.expect(AssertionError.class); + throw new AssertionError("the expected assertion error"); + } + } + + public static class ViolateAssumptionAndExpectException { + @Rule + public ExpectedException thrown= none(); + + @Test + public void violatedAssumption() { + // expect an exception, which is not an AssumptionViolatedException + thrown.expect(NullPointerException.class); + assumeTrue(false); + } + } + + public static class ThrowAssumptionViolatedExceptionButExpectOtherType { + @Rule + public ExpectedException thrown= none(); + + @Test + public void wrongException() { + thrown.handleAssumptionViolatedExceptions(); + thrown.expect(NullPointerException.class); + throw new AssumptionViolatedException(""); + } + } + + public static class ThrowExpectedAssumptionViolatedException { + @Rule + public ExpectedException thrown= none(); + + @Test + public void throwExpectAssumptionViolatedException() { + thrown.handleAssumptionViolatedExceptions(); + thrown.expect(AssumptionViolatedException.class); + throw new AssumptionViolatedException(""); + } + } + + private static Matcher startsWith(final String prefix) { + return new TypeSafeMatcher() { + public void describeTo(Description description) { + description.appendText("starts with "); + description.appendText(prefix); + } + + @Override + public boolean matchesSafely(String item) { + return item.startsWith(prefix); + } + }; + } +} \ No newline at end of file