Thursday, August 1, 2013

JUnit Rule for Verifying Logback Logging

Testing logging behavior is tricky: loggers are inevitably a dependency, and as such they should be mocked when unit-testing your component. However, most logging frameworks rely on static access to loggers, which makes mocking impossible, or at least cumbersome. This post by Pat Kua outlines some alternatives to the mocking approach, among which is creating another appender that will capture the output. I find this approach to be the most elegant, as it does not impose any awkward changes to the tested code.

In Kenshoo, we're shifting from using the good old log4j to the newer Logback implementation of the slf4j logging facade. This post by Aurelien Broszniowski suggests an easy implementation of the add-capturing-appender approach using Logback. Heavily relying on this implementation, we created a LogbackVerifier, a JUnit Rule that wraps the whole thing to make it more readable and reusable.

You would use it similarly to other verification rules (such as ExpectedException). In this example, we verify that service.doSomething(String) logs an info message on success and an error message (with an IllegalArgumentException object) on bad input:

Here's the LogbackVerifier implementation:

Implementation Notes:

  • of course, unlike your production code that can depend on Logback package in runtime only (and use slf4j in compile-time), your test code will need a Logback compile-time dependency to use the LogbackVerifier
  • This implementation uses Mockito, but one can easily replace it with any other mocking framework
  • The invocation order is not verified - it's easy to enhance this implementation to verify order. Since we're using Mockito, org.mockito.InOrder would do the trick
This post was authored by Tzach Zohar, architect at Kenshoo.

No comments:

Post a Comment