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 * @deprecated use {@code org.hamcrest.junit.ErrorCollector.checkThat()} 066 */ 067 @Deprecated 068 public <T> void checkThat(final T value, final Matcher<T> matcher) { 069 checkThat("", value, matcher); 070 } 071 072 /** 073 * Adds a failure with the given {@code reason} 074 * to the table if {@code matcher} does not match {@code value}. 075 * Execution continues, but the test will fail at the end if the match fails. 076 * 077 * @deprecated use {@code org.hamcrest.junit.ErrorCollector.checkThat()} 078 */ 079 @Deprecated 080 public <T> void checkThat(final String reason, final T value, final Matcher<T> matcher) { 081 checkSucceeds(new Callable<Object>() { 082 public Object call() throws Exception { 083 assertThat(reason, value, matcher); 084 return value; 085 } 086 }); 087 } 088 089 /** 090 * Adds to the table the exception, if any, thrown from {@code callable}. 091 * Execution continues, but the test will fail at the end if 092 * {@code callable} threw an exception. 093 */ 094 public <T> T checkSucceeds(Callable<T> callable) { 095 try { 096 return callable.call(); 097 } catch (AssumptionViolatedException e) { 098 AssertionError error = new AssertionError("Callable threw AssumptionViolatedException"); 099 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 */ 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 }