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