Permalink
Browse files

Actual exception added in ExpectedException

When using the ExpectedException to test for an exception to occur, it
throws an AssertionError when thrown exception does not match the
expected exception. Issue is however that in the JUnit runner results only
the actual exceptions message is shown and not the stacktrace. To fix
that, the actual exception is added to the cause of the AssertionError,
giving the exceptions in a format like:
java.lang.AssertionError: [reason]
  Expected: [expected exception]
     got: [actual exception + message]
 at [AssertionError stacktrace]
Caused by: [actual exception + message]
 at [actual exception stacktrace]
  • Loading branch information...
1 parent 45eaab7 commit 2cd3988479ae1195dcd38be325d2be1ea7d780e5 unknown committed Jan 3, 2012
@@ -111,7 +111,14 @@ public void evaluate() throws Throwable {
} catch (Throwable e) {
if (fMatcher == null)
throw e;
- Assert.assertThat(e, fMatcher);
+ try {
+ Assert.assertThat(e, fMatcher);
+ } catch (AssertionError ae) {
+ // add e as cause to have a complete error message in the
+ // results
+ ae.initCause(e);
+ throw ae;
+ }
return;
}
if (fMatcher != null)
@@ -6,12 +6,16 @@
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.CoreMatchers;
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;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
public class ExpectedExceptionRuleTest {
public static class HasExpectedException {
@@ -53,6 +57,44 @@ public void throwsNullPointerException() {
}
}
+ public static class ExpectedExceptionClause {
+ @Rule
+ public ExpectedException thrown= ExpectedException.none();
+
+ @Test
+ public void throwsNullPointerException() {
+ thrown.expect(NullPointerException.class);
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public static class CauseMatcher extends TypeSafeMatcher<Result> {
+ private final Class<? extends Throwable> causeClass;
+
+ public CauseMatcher(final Class<? extends Throwable> causeClass) {
+ this.causeClass= causeClass;
+ }
+
+ public void describeTo(final Description description) {
+ description.appendText("cause an instanceof ").appendText(causeClass.getName());
+ }
+
+ @Override
+ public boolean matchesSafely(final Result item) {
+ for(Failure f: item.getFailures())
+ {
@KentBeck

KentBeck Jan 3, 2012

We don't use brackets here

+ return CoreMatchers.instanceOf(causeClass).matches(f.getException().getCause());
+ }
+ return false;
+ }
+ }
+
+ @Test
+ public void expectedExceptionClauseExists() {
+ assertThat(new JUnitCore().run(ExpectedExceptionClause.class),
+ new CauseMatcher(IllegalArgumentException.class));
+ }
+
@Test
public void unExpectedExceptionFails() {
assertThat(

0 comments on commit 2cd3988

Please sign in to comment.