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 * @Rule 20 * public ErrorCollector collector= new ErrorCollector(); 21 * 22 * @Test 23 * public void example() { 24 * collector.addError(new Throwable("first thing went wrong")); 25 * collector.addError(new Throwable("second thing went wrong")); 26 * collector.checkThat(getResult(), not(containsString("ERROR!"))); 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