Creating a log asserter with JUnit 5 extensions

Julio Santana
2 min readJul 27, 2022

Extensions are a great add to JUnit 5. As the name indicates, this feature give the programmer the possibility to add new pieces to the framework that can be reused in many of his tests, showing that Software Development principles like DRY are also applicable to tests.

In JUnit 4 we already had @RunWith, but this was a bit limited. Still remember the pain when I had to use Mockito and Params on the same test, because I couldn’t put MockitoJUnitRunner and JUnitParamsRunner at the same time in RunWith. Fortunately new @ExtendWith accepts an array of extensions to be passed and make it really easy to create new ones. You only need to implement Extension interface and any of the callback you might be interested to add logic to like: BeforeAllCallback or AfterAllCallback.

As a practical example, let’s create a log asserter. This extension will do a task that is frequent and repetitive in many of our tests, It will capture our log.info statements parameters and assert they are as expected.

public class LogAsserterExtension implements BeforeEachCallback, Extension {private ListAppender<ILoggingEvent> appender;@Override
public void beforeEach(ExtensionContext extensionContext) {
appender = new ListAppender<>();
}
public void givenLoggerAppenderIsReady(Class<?> loggerOwner) {

Logger logger = (Logger) LoggerFactory.getLogger(loggerOwner);

appender.start();
logger.addAppender(appender);
}
public void thenTheRightMessageIsLogged(String msg, Object … params) {
List<ILoggingEvent> logsList = appender.list;

assertThat(logsList.get(0).getMessage(), is(msg));
assertThat(logsList.get(0).getArgumentArray(), is(params));
}
}

And this it. Now we are ready to use it as many unit tests as we want where first we will need to add it to ExtendWith or use the new RegisterExtension annotation

@RegisterExtension
LogAsserterExtension logAsserter = new LogAsserterExtension();

And then you are all set to use it in your tests

void when_a_method_that_log_data_is_called() {

logAsserter.givenLoggerAppenderIsReady(MyTestClass.class);
loginService.run(); logAsserter.thenTheRightMessageIsLogged(“Printing Message for user=
{} on date={}”, “User”,“12/12/2022”);
}

and we have a nice test that is able to check the log calls and assert them easily, all thanks to JUnit 5 extensions

--

--