[10397] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
| 2 | package org.openstreetmap.josm.testutils;
|
---|
| 3 |
|
---|
| 4 | import static org.openstreetmap.josm.testutils.ThrowableRootCauseMatcher.hasRootCause;
|
---|
| 5 |
|
---|
| 6 | import org.hamcrest.Matcher;
|
---|
| 7 | import org.junit.rules.ExpectedException;
|
---|
| 8 | import org.junit.rules.TestRule;
|
---|
| 9 | import org.junit.runner.Description;
|
---|
| 10 | import org.junit.runners.model.Statement;
|
---|
| 11 |
|
---|
| 12 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
---|
| 13 |
|
---|
| 14 | /**
|
---|
| 15 | * The {@code ExpectedRootException} behaves exactly as JUnit's {@link ExpectedException} rule.
|
---|
| 16 | * This class is needed to add {@link #expectRootCause} method, which has been rejected by JUnit developers,
|
---|
| 17 | * and {@code ExpectedException} cannot be extended because it has a private constructor.
|
---|
| 18 | * @see <a href="https://github.com/junit-team/junit4/pull/778">Github pull request</a>
|
---|
| 19 | */
|
---|
| 20 | public final class ExpectedRootException implements TestRule {
|
---|
| 21 |
|
---|
| 22 | private final ExpectedException rule = ExpectedException.none();
|
---|
| 23 |
|
---|
| 24 | /**
|
---|
| 25 | * Returns a {@linkplain TestRule rule} that expects no exception to be thrown (identical to behavior without this rule).
|
---|
| 26 | * @return {@code ExpectedRootException} instance
|
---|
| 27 | */
|
---|
| 28 | @SuppressFBWarnings("NM_CLASS_NOT_EXCEPTION")
|
---|
| 29 | public static ExpectedRootException none() {
|
---|
| 30 | return new ExpectedRootException();
|
---|
| 31 | }
|
---|
| 32 |
|
---|
| 33 | private ExpectedRootException() {
|
---|
| 34 | }
|
---|
| 35 |
|
---|
| 36 | /**
|
---|
| 37 | * Specifies the failure message for tests that are expected to throw an exception but do not throw any.
|
---|
| 38 | * You can use a {@code %s} placeholder for the description of the expected exception.
|
---|
| 39 | * E.g. "Test doesn't throw %s." will fail with the error message "Test doesn't throw an instance of foo.".
|
---|
| 40 | *
|
---|
| 41 | * @param message exception detail message
|
---|
| 42 | * @return the rule itself
|
---|
| 43 | */
|
---|
| 44 | public ExpectedRootException reportMissingExceptionWithMessage(String message) {
|
---|
| 45 | rule.reportMissingExceptionWithMessage(message);
|
---|
| 46 | return this;
|
---|
| 47 | }
|
---|
| 48 |
|
---|
| 49 | @Override
|
---|
| 50 | public Statement apply(Statement base, Description description) {
|
---|
| 51 | return rule.apply(base, description);
|
---|
| 52 | }
|
---|
| 53 |
|
---|
| 54 | /**
|
---|
| 55 | * Verify that your code throws an exception that is an instance of specific {@code type}.
|
---|
| 56 | * <pre> @Test
|
---|
| 57 | * public void throwsExceptionWithSpecificType() {
|
---|
| 58 | * thrown.expect(NullPointerException.class);
|
---|
| 59 | * throw new NullPointerException();
|
---|
| 60 | * }</pre>
|
---|
| 61 | * @param type Throwable type
|
---|
| 62 | * @return {@code this}
|
---|
| 63 | */
|
---|
| 64 | public ExpectedRootException expect(Class<? extends Throwable> type) {
|
---|
| 65 | rule.expect(type);
|
---|
| 66 | return this;
|
---|
| 67 | }
|
---|
| 68 |
|
---|
| 69 | /**
|
---|
| 70 | * Verify that your code throws an exception whose message contains a specific text.
|
---|
| 71 | * <pre> @Test
|
---|
| 72 | * public void throwsExceptionWhoseMessageContainsSpecificText() {
|
---|
| 73 | * thrown.expectMessage("happened");
|
---|
| 74 | * throw new NullPointerException("What happened?");
|
---|
| 75 | * }</pre>
|
---|
| 76 | * @param substring substring to expect in error message
|
---|
| 77 | * @return {@code this}
|
---|
| 78 | */
|
---|
| 79 | public ExpectedRootException expectMessage(String substring) {
|
---|
| 80 | rule.expectMessage(substring);
|
---|
| 81 | return this;
|
---|
| 82 | }
|
---|
| 83 |
|
---|
| 84 | /**
|
---|
| 85 | * Verify that your code throws an exception whose immediate cause is matched by the given Hamcrest matcher.
|
---|
| 86 | * <pre> @Test
|
---|
| 87 | * public void throwsExceptionWhoseCauseCompliesWithMatcher() {
|
---|
| 88 | * NullPointerException rootCause = new NullPointerException();
|
---|
| 89 | * IllegalStateException immediateCause = new IllegalStateException(rootCause);
|
---|
| 90 | * thrown.expectCause(isA(NullPointerException.class));
|
---|
| 91 | * throw new IllegalArgumentException(immediateCause);
|
---|
| 92 | * }</pre>
|
---|
| 93 | * @param expectedCause expected cause
|
---|
| 94 | * @return {@code this}
|
---|
| 95 | */
|
---|
| 96 | public ExpectedRootException expectCause(Matcher<? extends Throwable> expectedCause) {
|
---|
| 97 | rule.expectCause(expectedCause);
|
---|
| 98 | return this;
|
---|
| 99 | }
|
---|
| 100 |
|
---|
| 101 | /**
|
---|
| 102 | * Verify that you code throws an exception whose root cause is matched by the given Hamcrest matcher.
|
---|
| 103 | * <pre> @Test
|
---|
| 104 | * public void throwsExceptionWhoseRootCauseCompliesWithMatcher() {
|
---|
| 105 | * NullPointerException rootCause = new NullPointerException();
|
---|
| 106 | * IllegalStateException immediateCause = new IllegalStateException(rootCause);
|
---|
| 107 | * thrown.expectRootCause(isA(NullPointerException.class));
|
---|
| 108 | * throw new IllegalArgumentException(immediateCause);
|
---|
| 109 | * }</pre>
|
---|
| 110 | * @param expectedRootCause expected root cause
|
---|
| 111 | * @return {@code this}
|
---|
| 112 | */
|
---|
| 113 | public ExpectedRootException expectRootCause(Matcher<? extends Throwable> expectedRootCause) {
|
---|
| 114 | rule.expect(hasRootCause(expectedRootCause));
|
---|
| 115 | return this;
|
---|
| 116 | }
|
---|
| 117 | }
|
---|