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 extends Throwable> 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