Skip to content

Commit

Permalink
Add ErrorCollector.checkThrows()
Browse files Browse the repository at this point in the history
Closes #1305
  • Loading branch information
kcooney committed May 29, 2016
1 parent 24b8ee0 commit b8b21a2
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 13 deletions.
12 changes: 1 addition & 11 deletions src/main/java/org/junit/Assert.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.hamcrest.Matcher;
import org.hamcrest.MatcherAssert;
import org.junit.function.ThrowingRunnable;
import org.junit.internal.ArrayComparisonFailure;
import org.junit.internal.ExactComparisonCriteria;
import org.junit.internal.InexactComparisonCriteria;
Expand Down Expand Up @@ -960,17 +961,6 @@ public static <T> void assertThat(String reason, T actual,
MatcherAssert.assertThat(reason, actual, matcher);
}

/**
* This interface facilitates the use of expectThrows from Java 8. It allows method references
* to void methods (that declare checked exceptions) to be passed directly into expectThrows
* without wrapping. It is not meant to be implemented directly.
*
* @since 4.13
*/
public interface ThrowingRunnable {
void run() throws Throwable;
}

/**
* Asserts that {@code runnable} throws an exception of type {@code expectedThrowable} when
* executed. If it does not throw an exception, an {@link AssertionError} is thrown. If it
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/org/junit/function/ThrowingRunnable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.junit.function;

/**
* This interface facilitates the use of expectThrows from Java 8. It allows method references
* to void methods (that declare checked exceptions) to be passed directly into expectThrows
* without wrapping. It is not meant to be implemented directly.
*
* @since 4.13
*/
public interface ThrowingRunnable {
void run() throws Throwable;
}
21 changes: 21 additions & 0 deletions src/main/java/org/junit/rules/ErrorCollector.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package org.junit.rules;

import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertThrows;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import org.junit.function.ThrowingRunnable;

import org.hamcrest.Matcher;
import org.junit.runners.model.MultipleFailureException;
Expand Down Expand Up @@ -87,4 +89,23 @@ public <T> T checkSucceeds(Callable<T> callable) {
return null;
}
}

/**
* Adds a failure to the table if {@code runnable} does not throw an
* exception of type {@code expectedThrowable} when executed.
* Execution continues, but the test will fail at the end if the runnable
* does not throw an exception, or if it throws a different exception.
*
* @param expectedThrowable the expected type of the exception
* @param runnable a function that is expected to throw an exception when executed
* @since 4.13
*/
public void checkThrows(Class<? extends Throwable> expectedThrowable, ThrowingRunnable runnable) {
try {
assertThrows(expectedThrowable, runnable);
} catch (AssertionError e) {
addError(e);
}
}

}
63 changes: 62 additions & 1 deletion src/test/java/org/junit/rules/VerifierRuleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.results.PrintableResult;
import org.junit.function.ThrowingRunnable;

public class VerifierRuleTest {
public static class UsesErrorCollector {
Expand Down Expand Up @@ -123,6 +124,66 @@ public void usedErrorCollectorCheckSucceedsShouldPass() {
assertThat(testResult, isSuccessful());
}

public static class UsesErrorCollectorCheckThrowsMatchingClass {
@Rule
public ErrorCollector collector = new ErrorCollector();

@Test
public void example() {
collector.checkThrows(IllegalArgumentException.class, new ThrowingRunnable() {
public void run() throws Throwable {
throw new IllegalArgumentException();
}
});
}
}

@Test
public void usedErrorCollectorCheckThrowsMatchingClassShouldPass() {
PrintableResult testResult = testResult(UsesErrorCollectorCheckThrowsMatchingClass.class);
assertThat(testResult, isSuccessful());
}

public static class UsesErrorCollectorCheckThrowsClassMismatch {
@Rule
public ErrorCollector collector = new ErrorCollector();

@Test
public void example() {
collector.checkThrows(IllegalArgumentException.class, new ThrowingRunnable() {
public void run() throws Throwable {
throw new NullPointerException();
}
});
}
}

@Test
public void usedErrorCollectorCheckThrowsClassMismatchShouldFail() {
PrintableResult testResult = testResult(UsesErrorCollectorCheckThrowsClassMismatch.class);
assertThat(testResult, hasFailureContaining(
"expected:<IllegalArgumentException> but was:<NullPointerException>"));
}

public static class UsesErrorCollectorCheckThrowsNothingThrown {
@Rule
public ErrorCollector collector = new ErrorCollector();

@Test
public void example() {
collector.checkThrows(IllegalArgumentException.class, new ThrowingRunnable() {
public void run() throws Throwable {
}
});
}
}

@Test
public void usedErrorCollectorCheckThrowsNothingThrownShouldFail() {
PrintableResult testResult = testResult(UsesErrorCollectorCheckThrowsNothingThrown.class);
assertThat(testResult, hasFailureContaining("but nothing was thrown"));
}

private static String sequence;

public static class UsesVerifier {
Expand All @@ -146,4 +207,4 @@ public void verifierRunsAfterTest() {
assertThat(testResult(UsesVerifier.class), isSuccessful());
assertEquals("test verify ", sequence);
}
}
}
2 changes: 1 addition & 1 deletion src/test/java/org/junit/tests/assertion/AssertionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
import java.math.BigDecimal;

import org.junit.Assert;
import org.junit.Assert.ThrowingRunnable;
import org.junit.ComparisonFailure;
import org.junit.Test;
import org.junit.function.ThrowingRunnable;
import org.junit.internal.ArrayComparisonFailure;

/**
Expand Down

0 comments on commit b8b21a2

Please sign in to comment.