Home | History | Annotate | Download | only in rules
      1 package org.junit.rules;
      2 
      3 import static org.junit.Assert.assertThat;
      4 
      5 import java.util.ArrayList;
      6 import java.util.List;
      7 import java.util.concurrent.Callable;
      8 
      9 import org.hamcrest.Matcher;
     10 import org.junit.runners.model.MultipleFailureException;
     11 
     12 /**
     13  * The ErrorCollector rule allows execution of a test to continue after the
     14  * first problem is found (for example, to collect _all_ the incorrect rows in a
     15  * table, and report them all at once):
     16  *
     17  * <pre>
     18  * public static class UsesErrorCollectorTwice {
     19  * 	&#064;Rule
     20  * 	public ErrorCollector collector= new ErrorCollector();
     21  *
     22  * &#064;Test
     23  * public void example() {
     24  *      collector.addError(new Throwable(&quot;first thing went wrong&quot;));
     25  *      collector.addError(new Throwable(&quot;second thing went wrong&quot;));
     26  *      collector.checkThat(getResult(), not(containsString(&quot;ERROR!&quot;)));
     27  *      // all lines will run, and then a combined failure logged at the end.
     28  *     }
     29  * }
     30  * </pre>
     31  *
     32  * @since 4.7
     33  */
     34 public class ErrorCollector extends Verifier {
     35     private List<Throwable> errors = new ArrayList<Throwable>();
     36 
     37     @Override
     38     protected void verify() throws Throwable {
     39         MultipleFailureException.assertEmpty(errors);
     40     }
     41 
     42     /**
     43      * Adds a Throwable to the table.  Execution continues, but the test will fail at the end.
     44      */
     45     public void addError(Throwable error) {
     46         errors.add(error);
     47     }
     48 
     49     /**
     50      * Adds a failure to the table if {@code matcher} does not match {@code value}.
     51      * Execution continues, but the test will fail at the end if the match fails.
     52      */
     53     public <T> void checkThat(final T value, final Matcher<T> matcher) {
     54         checkThat("", value, matcher);
     55     }
     56 
     57     /**
     58      * Adds a failure with the given {@code reason}
     59      * to the table if {@code matcher} does not match {@code value}.
     60      * Execution continues, but the test will fail at the end if the match fails.
     61      */
     62     public <T> void checkThat(final String reason, final T value, final Matcher<T> matcher) {
     63         checkSucceeds(new Callable<Object>() {
     64             public Object call() throws Exception {
     65                 assertThat(reason, value, matcher);
     66                 return value;
     67             }
     68         });
     69     }
     70 
     71     /**
     72      * Adds to the table the exception, if any, thrown from {@code callable}.
     73      * Execution continues, but the test will fail at the end if
     74      * {@code callable} threw an exception.
     75      */
     76     public <T> T checkSucceeds(Callable<T> callable) {
     77         try {
     78             return callable.call();
     79         } catch (Throwable e) {
     80             addError(e);
     81             return null;
     82         }
     83     }
     84 }
     85