001 package org.junit.rules;
002
003 import static org.junit.Assert.assertThat;
004 import static org.junit.Assert.assertThrows;
005
006 import java.util.ArrayList;
007 import java.util.List;
008 import java.util.concurrent.Callable;
009
010 import org.junit.function.ThrowingRunnable;
011 import org.junit.internal.AssumptionViolatedException;
012 import org.hamcrest.Matcher;
013 import org.junit.runners.model.MultipleFailureException;
014
015 /**
016 * The ErrorCollector rule allows execution of a test to continue after the
017 * first problem is found (for example, to collect _all_ the incorrect rows in a
018 * table, and report them all at once):
019 *
020 * <pre>
021 * public static class UsesErrorCollectorTwice {
022 * @Rule
023 * public ErrorCollector collector= new ErrorCollector();
024 *
025 * @Test
026 * public void example() {
027 * collector.addError(new Throwable("first thing went wrong"));
028 * collector.addError(new Throwable("second thing went wrong"));
029 * collector.checkThat(getResult(), not(containsString("ERROR!")));
030 * // all lines will run, and then a combined failure logged at the end.
031 * }
032 * }
033 * </pre>
034 *
035 * @since 4.7
036 */
037 public class ErrorCollector extends Verifier {
038 private List<Throwable> errors = new ArrayList<Throwable>();
039
040 @Override
041 protected void verify() throws Throwable {
042 MultipleFailureException.assertEmpty(errors);
043 }
044
045 /**
046 * Adds a Throwable to the table. Execution continues, but the test will fail at the end.
047 */
048 public void addError(Throwable error) {
049 if (error == null) {
050 throw new NullPointerException("Error cannot be null");
051 }
052 if (error instanceof AssumptionViolatedException) {
053 AssertionError e = new AssertionError(error.getMessage());
054 e.initCause(error);
055 errors.add(e);
056 } else {
057 errors.add(error);
058 }
059 }
060
061 /**
062 * Adds a failure to the table if {@code matcher} does not match {@code value}.
063 * Execution continues, but the test will fail at the end if the match fails.
064 */
065 public <T> void checkThat(final T value, final Matcher<T> matcher) {
066 checkThat("", value, matcher);
067 }
068
069 /**
070 * Adds a failure with the given {@code reason}
071 * to the table if {@code matcher} does not match {@code value}.
072 * Execution continues, but the test will fail at the end if the match fails.
073 */
074 public <T> void checkThat(final String reason, final T value, final Matcher<T> matcher) {
075 checkSucceeds(new Callable<Object>() {
076 public Object call() throws Exception {
077 assertThat(reason, value, matcher);
078 return value;
079 }
080 });
081 }
082
083 /**
084 * Adds to the table the exception, if any, thrown from {@code callable}.
085 * Execution continues, but the test will fail at the end if
086 * {@code callable} threw an exception.
087 */
088 public <T> T checkSucceeds(Callable<T> callable) {
089 try {
090 return callable.call();
091 } catch (AssumptionViolatedException e) {
092 AssertionError error = new AssertionError("Callable threw AssumptionViolatedException");
093 error.initCause(e);
094 addError(error);
095 return null;
096 } catch (Throwable e) {
097 addError(e);
098 return null;
099 }
100 }
101
102 /**
103 * Adds a failure to the table if {@code runnable} does not throw an
104 * exception of type {@code expectedThrowable} when executed.
105 * Execution continues, but the test will fail at the end if the runnable
106 * does not throw an exception, or if it throws a different exception.
107 *
108 * @param expectedThrowable the expected type of the exception
109 * @param runnable a function that is expected to throw an exception when executed
110 * @since 4.13
111 */
112 public void checkThrows(Class<? extends Throwable> expectedThrowable, ThrowingRunnable runnable) {
113 try {
114 assertThrows(expectedThrowable, runnable);
115 } catch (AssertionError e) {
116 addError(e);
117 }
118 }
119
120 }