I have some code-under-test that calls on a Java logger to report its status. In the JUnit test code, I would like to verify that the correct log entry was made in this logger. Something along the following lines:
methodUnderTest(bool x){
if(x)
logger.info("x happened")
}
@Test tester(){
// perhaps setup a logger first.
methodUnderTest(true);
assertXXXXXX(loggedLevel(),Level.INFO);
}
I suppose that this could be done with a specially adapted logger (or handler, or formatter), but I would prefer to re-use a solution that already exists. (And, to be honest, it is not clear to me how to get at the logRecord from a logger, but suppose that that's possible.)
Mocking the Appender can help capture the log lines. Find sample on: http://clearqa.blogspot.co.uk/2016/12/test-log-lines.html
Use the below code. I am using same code for my spring integration test where I am using log back for logging. Use method assertJobIsScheduled to assert the text printed in the log.
Effectively you are testing a side-effect of a dependent class. For unit testing you need only to verify that
was called with the correct parameter. Hence use a mocking framework to emulate logger and that will allow you to test your own class's behaviour.
Another idea worth mentioning, although it's an older topic, is creating a CDI producer to inject your logger so the mocking becomes easy. (And it also gives the advantage of not having to declare the "whole logger statement" anymore, but that's off-topic)
Example:
Creating the logger to inject:
The qualifier:
Using the logger in your production code:
Testing the logger in your test code (giving an easyMock example):
Inspired by @RonaldBlaschke's solution, I came up with this:
... which allows you to do:
You could probably make it use hamcrest in a smarter way, but I've left it at this.
Here is a simple and efficient Logback solution.
It doesn't require to add/create any new class.
It relies on
ListAppender
: a whitebox logback appender where log entries are added in apublic List
field that we could so use to make our assertions.Here is a simple example.
Foo class :
FooTest class :
JUnit assertions don't sound very adapted to assert some specific properties of the list elements.
Matcher/assertion libraries as AssertJ or Hamcrest appears better for that :
With AssertJ it would be :