Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make log4j error() calls throw an exception in jUnit tests?

Tags:

java

junit

log4j

I have a Java project being tested with JUnit (mix of Junit 3 and 4 style), where the classes under test might log a log4j error. I would like to make a unit test fail if such an error is logged.

Is there a generic way to configure either log4j or the unit test infrastructure to make any call to a log4j error() method in the code under test throw a runtime exception and therefore fail the test? AOP might be one way, but I'm interested in other possibilities too.

The intention here is to weed out places in code where log4j error() is being used incorrectly. That is, when an error is logged but no exception or error handling has occurred, either it's not really an error, or it is and should be raised.

eg:

public class MyTest extends TestCase {
    public void testLogAnError() {
        // Want to make this fail
        new MyClass().logAnError();
    }
}

public class MyClass() {
    static Logger logger = Logger.getLogger("foo");

    public void logAnError() {
        // I'm logging an error, but not doing anything about it
        logger.error("Something bad, or is it?");
        // TODO throw an exception or don't log an error if there isn't one
    }
}

Update: This is what the solution I'm using currently looks like. It is based on sbridges' answer (added to test class):

private static final Appender crashAndBurnAppender = new NullAppender () {
    public void doAppend(LoggingEvent event) {
         if(event.getLevel() == Level.ERROR) {
              throw new AssertionError("logged at error:" + event.getMessage());
         }
    }
};

Then in setUp:

Logger.getRootLogger().addAppender(crashAndBurnAppender);

And tearDown:

Logger.getRootLogger().removeAppender(crashAndBurnAppender);
like image 707
Rog Avatar asked Apr 13 '11 05:04

Rog


1 Answers

You can create a new Appender that throws an AssertionError when you log at error level.

Something like,

class TestAppender extends AppenderSkeleton {
    public void doAppend(LoggingEvent event) {
         if(event.getLevel() == Level.Error) {
              throw new AssertionError("logged at error:" + event.getMessage());
         }
    }
}

In your test do,

Logger.getRootLogger().addAppender(new TestAppender());

Edit : as Ralph pointed out, remove the TestAppender after you finish the test.

like image 170
sbridges Avatar answered Nov 03 '22 13:11

sbridges