All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.junit.rules.ExpectedException Maven / Gradle / Ivy

Go to download

JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck.

There is a newer version: 4.13.2
Show newest version
package org.junit.rules;

import static java.lang.String.format;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.junit.internal.matchers.ThrowableCauseMatcher.hasCause;
import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage;
import org.hamcrest.Matcher;
import org.hamcrest.StringDescription;
import org.junit.AssumptionViolatedException;
import org.junit.runners.model.Statement;

/**
 * The {@code ExpectedException} rule allows you to verify that your code
 * throws a specific exception.
 *
 * 

Usage

* *
 public class SimpleExpectedExceptionTest {
 *     @Rule
 *     public ExpectedException thrown = ExpectedException.none();
 *
 *     @Test
 *     public void throwsNothing() {
 *         // no exception expected, none thrown: passes.
 *     }
 *
 *     @Test
 *     public void throwsExceptionWithSpecificType() {
 *         thrown.expect(NullPointerException.class);
 *         throw new NullPointerException();
 *     }
 * }
* *

You have to add the {@code ExpectedException} rule to your test. * This doesn't affect your existing tests (see {@code throwsNothing()}). * After specifying the type of the expected exception your test is * successful when such an exception is thrown and it fails if a * different or no exception is thrown. * *

This rule does not perform any special magic to make execution continue * as if the exception had not been thrown. So it is nearly always a mistake * for a test method to have statements after the one that is expected to * throw the exception. * *

Instead of specifying the exception's type you can characterize the * expected exception based on other criteria, too: * *

    *
  • The exception's message contains a specific text: {@link #expectMessage(String)}
  • *
  • The exception's message complies with a Hamcrest matcher: {@link #expectMessage(Matcher)}
  • *
  • The exception's cause complies with a Hamcrest matcher: {@link #expectCause(Matcher)}
  • *
  • The exception itself complies with a Hamcrest matcher: {@link #expect(Matcher)}
  • *
* *

You can combine any of the presented expect-methods. The test is * successful if all specifications are met. *

 @Test
 * public void throwsException() {
 *     thrown.expect(NullPointerException.class);
 *     thrown.expectMessage("happened");
 *     throw new NullPointerException("What happened?");
 * }
* *

It is recommended to set the {@link org.junit.Rule#order() order} of the * {@code ExpectedException} to {@code Integer.MAX_VALUE} if it is used together * with another rule that handles exceptions, e.g. {@link ErrorCollector}. * Otherwise failing tests may be successful. *

 @Rule(order = Integer.MAX_VALUE)
 * public ExpectedException thrown = ExpectedException.none();
* *

AssumptionViolatedExceptions

*

JUnit uses {@link AssumptionViolatedException}s for indicating that a test * provides no useful information. (See {@link org.junit.Assume} for more * information.) You have to call {@code assume} methods before you set * expectations of the {@code ExpectedException} rule. In this case the rule * will not handle consume the exceptions and it can be handled by the * framework. E.g. the following test is ignored by JUnit's default runner. * *

 @Test
 * public void ignoredBecauseOfFailedAssumption() {
 *     assumeTrue(false); // throws AssumptionViolatedException
 *     thrown.expect(NullPointerException.class);
 * }
* *

AssertionErrors

* *

JUnit uses {@link AssertionError}s for indicating that a test is failing. You * have to call {@code assert} methods before you set expectations of the * {@code ExpectedException} rule, if they should be handled by the framework. * E.g. the following test fails because of the {@code assertTrue} statement. * *

 @Test
 * public void throwsUnhandled() {
 *     assertTrue(false); // throws AssertionError
 *     thrown.expect(NullPointerException.class);
 * }
* *

Missing Exceptions

*

By default missing exceptions are reported with an error message * like "Expected test to throw an instance of foo". You can configure a different * message by means of {@link #reportMissingExceptionWithMessage(String)}. You * can use a {@code %s} placeholder for the description of the expected * exception. E.g. "Test doesn't throw %s." will fail with the error message * "Test doesn't throw an instance of foo.". * * @deprecated Since 4.13 * {@link org.junit.Assert#assertThrows(Class, org.junit.function.ThrowingRunnable) * Assert.assertThrows} can be used to verify that your code throws a specific * exception. * @since 4.7 */ public class ExpectedException implements TestRule { /** * Returns a {@linkplain TestRule rule} that expects no exception to * be thrown (identical to behavior without this rule). */ public static ExpectedException none() { return new ExpectedException(); } private final ExpectedExceptionMatcherBuilder matcherBuilder = new ExpectedExceptionMatcherBuilder(); private String missingExceptionMessage= "Expected test to throw %s"; private ExpectedException() { } /** * This method does nothing. Don't use it. * @deprecated AssertionErrors are handled by default since JUnit 4.12. Just * like in JUnit <= 4.10. */ @Deprecated public ExpectedException handleAssertionErrors() { return this; } /** * This method does nothing. Don't use it. * @deprecated AssumptionViolatedExceptions are handled by default since * JUnit 4.12. Just like in JUnit <= 4.10. */ @Deprecated public ExpectedException handleAssumptionViolatedExceptions() { return this; } /** * Specifies the failure message for tests that are expected to throw * an exception but do not throw any. You can use a {@code %s} placeholder for * the description of the expected exception. E.g. "Test doesn't throw %s." * will fail with the error message * "Test doesn't throw an instance of foo.". * * @param message exception detail message * @return the rule itself */ public ExpectedException reportMissingExceptionWithMessage(String message) { missingExceptionMessage = message; return this; } public Statement apply(Statement base, org.junit.runner.Description description) { return new ExpectedExceptionStatement(base); } /** * Verify that your code throws an exception that is matched by * a Hamcrest matcher. *

 @Test
     * public void throwsExceptionThatCompliesWithMatcher() {
     *     NullPointerException e = new NullPointerException();
     *     thrown.expect(is(e));
     *     throw e;
     * }
* * @deprecated use {@code org.hamcrest.junit.ExpectedException.expect()} */ @Deprecated public void expect(Matcher matcher) { matcherBuilder.add(matcher); } /** * Verify that your code throws an exception that is an * instance of specific {@code type}. *
 @Test
     * public void throwsExceptionWithSpecificType() {
     *     thrown.expect(NullPointerException.class);
     *     throw new NullPointerException();
     * }
*/ public void expect(Class type) { expect(instanceOf(type)); } /** * Verify that your code throws an exception whose message contains * a specific text. *
 @Test
     * public void throwsExceptionWhoseMessageContainsSpecificText() {
     *     thrown.expectMessage("happened");
     *     throw new NullPointerException("What happened?");
     * }
*/ public void expectMessage(String substring) { expectMessage(containsString(substring)); } /** * Verify that your code throws an exception whose message is matched * by a Hamcrest matcher. *
 @Test
     * public void throwsExceptionWhoseMessageCompliesWithMatcher() {
     *     thrown.expectMessage(startsWith("What"));
     *     throw new NullPointerException("What happened?");
     * }
* * @deprecated use {@code org.hamcrest.junit.ExpectedException.expectMessage()} */ @Deprecated public void expectMessage(Matcher matcher) { expect(hasMessage(matcher)); } /** * Verify that your code throws an exception whose cause is matched by * a Hamcrest matcher. *
 @Test
     * public void throwsExceptionWhoseCauseCompliesWithMatcher() {
     *     NullPointerException expectedCause = new NullPointerException();
     *     thrown.expectCause(is(expectedCause));
     *     throw new IllegalArgumentException("What happened?", cause);
     * }
* * @deprecated use {@code org.hamcrest.junit.ExpectedException.expectCause()} */ @Deprecated public void expectCause(Matcher expectedCause) { expect(hasCause(expectedCause)); } /** * Check if any Exception is expected. * @since 4.13 */ public final boolean isAnyExceptionExpected() { return matcherBuilder.expectsThrowable(); } private class ExpectedExceptionStatement extends Statement { private final Statement next; public ExpectedExceptionStatement(Statement base) { next = base; } @Override public void evaluate() throws Throwable { try { next.evaluate(); } catch (Throwable e) { handleException(e); return; } if (isAnyExceptionExpected()) { failDueToMissingException(); } } } private void handleException(Throwable e) throws Throwable { if (isAnyExceptionExpected()) { assertThat(e, matcherBuilder.build()); } else { throw e; } } private void failDueToMissingException() throws AssertionError { fail(missingExceptionMessage()); } private String missingExceptionMessage() { String expectation= StringDescription.toString(matcherBuilder.build()); return format(missingExceptionMessage, expectation); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy