Jonathan Lebrun Jonathan Lebrun - 3 months ago 21
Java Question

The Junit message (expected was ...) is not displayed in the console with logback

I use Logback with SLF4J (migrate from log4j) and when I run a junit test that fails, the reason why the test fails is not displayed (AssertionFailedError : expected is <> but was <>)

All other logs are running.

My logback configuration :

<configuration>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %msg%n</pattern>
</encoder>
<filter class="com.jle.athleges.logback.TrashFilter">
<logger>org.springframework</logger>
<level>ERROR</level>
</filter>
</appender>

<appender name="TRASH_FILE_APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/logback_trash.log</file>

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>logs/trash.log.%d{yyyy-MM-dd-HH-mm}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>

<logger name="org.springframework">
<appender-ref ref="TRASH_FILE_APPENDER" />
</logger>

<root level="debug">
<appender-ref ref="STDOUT" />
<appender-ref ref="TRASH_FILE_APPENDER" />
</root>




My Unit Test :

@Test
public void getAllMembers() {
log.debug("Start getAllMember");

long sizeBefore = repository.count();
Member a = new Member();
a.setFirstname("aaa");
a.setLastname("hhh");
a.setId(2L);

Member b = new Member();
b.setFirstname("aaa");
b.setLastname("hhh");
b.setId(1L);
memberService.save(a);
memberService.save(b);

Assert.assertTrue(memberService.getAll().size() == 0);
log.debug("End getAllMember");
}


As you see my service return more than 0 elements and my test fails. So, I receive this message :

java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:86)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertTrue(Assert.java:52)
at com.jle.athleges.test.integration.MemberServiceImpTest.getAllMembers(MemberServiceImpTest.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at ...


With Log4J the statement was java.lang.AssertionError Expected <0> was <2>

Even if I use DEBUG instead of ERROR, the result is the same.

I don't understand why the part Expected <0> was <2> is not displayed

Thanks

Answer

You are asserting a boolean:

Assert.assertTrue(memberService.getAll().size() == 0);

The framework just knows you want to see a true value, but not what the source of the value is. By the time the assertion is called, memberService.getAll().size() == 0 has already been evaluated. Usually it's a better idea to use more specific assertions.

You could start with

assertEquals(0, memberService.getAll().size())

That would give you the Expected <0> was <2> output.

But I personally prefer the Hamcrest style of assertions:

assertThat(memberService.getAll(), is(empty()))

where both is and empty are static imports:

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.collection.IsEmptyCollection.empty;

This makes sure both the test code and its output are most readable.

Comments