JUnit ErrorCollector Verify All Asserts Before Failing
When JUnit encounters an assert failure it’ll immediately fail the test. Sometimes this is not desirable and you want to inspect all the assert statements before failing the test. The JUnit ErrorCollector rule was introduced to address this problem. Like the name indicates, the ErrorCollector
rule collects all the assert statements. When It encounters an assert failure, it’ll not fail the test immediately but only at the end of the test.
Using The JUnit ErrorCollector
The first test does a simple equality assert. When it encounters an assert failure, it’ll immediately fail the test without evaluating the next assert statements.
Alternatively, we could use the ErrorCollector
rule which let’s us inspect all the assert statements before failing the test.
package com.memorynotfound.test;
import org.junit.*;
import org.junit.rules.ErrorCollector;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
public class TestErrorCollectorRule {
@Rule
public ErrorCollector collector = new ErrorCollector();
@Test
public void fails_first_assert_mismatch(){
assertEquals(1, 2);
assertEquals(2, 3);
}
@Test
public void fails_after_execution(){
collector.checkThat("a", equalTo("b"));
collector.checkThat(1, equalTo(2));
}
}
The previous tests generate the following report. Notice that there are only three failures because the first test only generates a single failure.
<?xml version="1.0" encoding="UTF-8"?>
<testsuite failures="3" time="0.031" errors="0" skipped="0" tests="3" name="com.memorynotfound.test.TestErrorCollectorRule">
<testcase time="0.015" classname="com.memorynotfound.test.TestErrorCollectorRule" name="fails_after_execution">
<failure message=" Expected: "b" but: was "a"" type="java.lang.AssertionError">java.lang.AssertionError:
Expected: "b"
but: was "a"
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.junit.Assert.assertThat(Assert.java:956)
at org.junit.rules.ErrorCollector$1.call(ErrorCollector.java:65)
at org.junit.rules.ErrorCollector.checkSucceeds(ErrorCollector.java:78)
at org.junit.rules.ErrorCollector.checkThat(ErrorCollector.java:63)
at org.junit.rules.ErrorCollector.checkThat(ErrorCollector.java:54)
at com.memorynotfound.test.TestErrorCollectorRule.fails_after_execution(TestErrorCollectorRule.java:21)
at ...
</failure>
</testcase>
<testcase time="0.016" classname="com.memorynotfound.test.TestErrorCollectorRule" name="fails_after_execution">
<failure message=" Expected: <2> but: was <1>" type="java.lang.AssertionError">java.lang.AssertionError:
Expected: <2>
but: was <1>
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.junit.Assert.assertThat(Assert.java:956)
at org.junit.rules.ErrorCollector$1.call(ErrorCollector.java:65)
at org.junit.rules.ErrorCollector.checkSucceeds(ErrorCollector.java:78)
at org.junit.rules.ErrorCollector.checkThat(ErrorCollector.java:63)
at org.junit.rules.ErrorCollector.checkThat(ErrorCollector.java:54)
at com.memorynotfound.test.TestErrorCollectorRule.fails_after_execution(TestErrorCollectorRule.java:22)
at ...
</failure>
</testcase>
<testcase time="0" classname="com.memorynotfound.test.TestErrorCollectorRule" name="fails_first_assert_mismatch">
<failure message="expected:<1> but was:<2>" type="java.lang.AssertionError">java.lang.AssertionError: expected:<1> but was:<2>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:645)
at org.junit.Assert.assertEquals(Assert.java:631)
at com.memorynotfound.test.TestErrorCollectorRule.fails_first_assert_mismatch(TestErrorCollectorRule.java:15)
at ...
</failure>
</testcase>
</testsuite>