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(boolean x) {
if(x) { logger.info("x happened"); }
}
@Test tester() {
// perhaps set up 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 reuse 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.)
Thanks a lot for these (surprisingly) quick and helpful answers; they put me on the right way for my solution.
The codebase were I want to use this, uses java.util.logging as its logger mechanism, and I don't feel at home enough in those codes to completely change that to log4j or to logger interfaces/facades. But based on these suggestions, I 'hacked-up' a j.u.l.handler extension and that works as a treat.
A short summary follows. Extend java.util.logging.Handler
:
class LogHandler extends Handler
{
Level lastLevel = Level.FINEST;
public Level checkLevel() {
return lastLevel;
}
public void publish(LogRecord record) {
lastLevel = record.getLevel();
}
public void close(){}
public void flush(){}
}
Obviously, you can store as much as you like/want/need from the LogRecord
, or push them all into a stack until you get an overflow.
In the preparation for the junit-test, you create a java.util.logging.Logger
and add such a new LogHandler
to it:
@Test tester() {
Logger logger = Logger.getLogger("my junit-test logger");
LogHandler handler = new LogHandler();
handler.setLevel(Level.ALL);
logger.setUseParentHandlers(false);
logger.addHandler(handler);
logger.setLevel(Level.ALL);
The call to setUseParentHandlers()
is to silence the normal handlers, so that (for this junit-test run) no unnecessary logging happens. Do whatever your code-under-test needs to use this logger, run the test and assertEquality:
libraryUnderTest.setLogger(logger);
methodUnderTest(true); // see original question.
assertEquals("Log level as expected?", Level.INFO, handler.checkLevel() );
}
(Of course, you would move large part of this work into a @Before
method and make assorted other improvements, but that would clutter this presentation.)