• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.junit.rules;
2 
3 import static org.junit.Assert.assertThat;
4 import static org.junit.Assert.assertThrows;
5 
6 import java.util.ArrayList;
7 import java.util.List;
8 import java.util.concurrent.Callable;
9 
10 import org.junit.function.ThrowingRunnable;
11 import org.junit.internal.AssumptionViolatedException;
12 import org.hamcrest.Matcher;
13 import org.junit.runners.model.MultipleFailureException;
14 
15 /**
16  * The ErrorCollector rule allows execution of a test to continue after the
17  * first problem is found (for example, to collect _all_ the incorrect rows in a
18  * table, and report them all at once):
19  *
20  * <pre>
21  * public static class UsesErrorCollectorTwice {
22  * 	&#064;Rule
23  * 	public ErrorCollector collector= new ErrorCollector();
24  *
25  * &#064;Test
26  * public void example() {
27  *      collector.addError(new Throwable(&quot;first thing went wrong&quot;));
28  *      collector.addError(new Throwable(&quot;second thing went wrong&quot;));
29  *      collector.checkThat(getResult(), not(containsString(&quot;ERROR!&quot;)));
30  *      // all lines will run, and then a combined failure logged at the end.
31  *     }
32  * }
33  * </pre>
34  *
35  * @since 4.7
36  */
37 public class ErrorCollector extends Verifier {
38     private List<Throwable> errors = new ArrayList<Throwable>();
39 
40     @Override
verify()41     protected void verify() throws Throwable {
42         MultipleFailureException.assertEmpty(errors);
43     }
44 
45     /**
46      * Adds a Throwable to the table.  Execution continues, but the test will fail at the end.
47      */
addError(Throwable error)48     public void addError(Throwable error) {
49         if (error == null) {
50             throw new NullPointerException("Error cannot be null");
51         }
52         // BEGIN Android-changed: Don't convert assumption failures to errors. b/181123057
53         // Submitted upstream: https://github.com/junit-team/junit4/issues/1703
54         /*
55         if (error instanceof AssumptionViolatedException) {
56             AssertionError e = new AssertionError(error.getMessage());
57             e.initCause(error);
58             errors.add(e);
59         } else {
60             errors.add(error);
61         }
62         */
63         // END Android-changed: Don't convert assumption failures to errors. b/181123057
64         errors.add(error);
65     }
66 
67     /**
68      * Adds a failure to the table if {@code matcher} does not match {@code value}.
69      * Execution continues, but the test will fail at the end if the match fails.
70      */
checkThat(final T value, final Matcher<T> matcher)71     public <T> void checkThat(final T value, final Matcher<T> matcher) {
72         checkThat("", value, matcher);
73     }
74 
75     /**
76      * Adds a failure with the given {@code reason}
77      * to the table if {@code matcher} does not match {@code value}.
78      * Execution continues, but the test will fail at the end if the match fails.
79      */
checkThat(final String reason, final T value, final Matcher<T> matcher)80     public <T> void checkThat(final String reason, final T value, final Matcher<T> matcher) {
81         checkSucceeds(new Callable<Object>() {
82             public Object call() throws Exception {
83                 assertThat(reason, value, matcher);
84                 return value;
85             }
86         });
87     }
88 
89     /**
90      * Adds to the table the exception, if any, thrown from {@code callable}.
91      * Execution continues, but the test will fail at the end if
92      * {@code callable} threw an exception.
93      */
checkSucceeds(Callable<T> callable)94     public <T> T checkSucceeds(Callable<T> callable) {
95         try {
96             return callable.call();
97         } catch (AssumptionViolatedException e) {
98             AssertionError error = new AssertionError("Callable threw AssumptionViolatedException");
99             error.initCause(e);
100             addError(error);
101             return null;
102         } catch (Throwable e) {
103             addError(e);
104             return null;
105         }
106     }
107 
108     /**
109      * Adds a failure to the table if {@code runnable} does not throw an
110      * exception of type {@code expectedThrowable} when executed.
111      * Execution continues, but the test will fail at the end if the runnable
112      * does not throw an exception, or if it throws a different exception.
113      *
114      * @param expectedThrowable the expected type of the exception
115      * @param runnable       a function that is expected to throw an exception when executed
116      * @since 4.13
117      */
checkThrows(Class<? extends Throwable> expectedThrowable, ThrowingRunnable runnable)118     public void checkThrows(Class<? extends Throwable> expectedThrowable, ThrowingRunnable runnable) {
119         try {
120             assertThrows(expectedThrowable, runnable);
121         } catch (AssertionError e) {
122             addError(e);
123         }
124     }
125 
126 }
127