Search code examples
javalog4j2jmockit

Problems using JMockit with log4j 2.9.0


I'm trying to use JMockit to test that a certain logging operation takes place:

public class LogClass1 {

    public void doLog() {
        Logger logger = LogManager.getLogger(LogClass1.class);
        logger.info("This is a log message for {}", "arg1");
    }
}

public class LogClass1Test {

    @Mocked
    private Logger logger;

    @Tested
    private LogClass1 x;

    @Before
    public void setup() {
        x = new LogClass1();
    }

    @Test
    public void testDoLog() {
        new Expectations() {
            {
                logger.info("This is a log message for {}", "arg1");
            }
        };
        x.doLog();
    }

}

But this results in a "missing 1 invocation to org.apache.logging.log4j.Logger#info" error.

I've done similar mocking with log4j 1.x in the past, and I haven't had this problem. I'm wondering if there's some issue because log4j 2.x seems to have many more overloads of its info() methods.

I tried changing "arg1" to (Object)"arg1" in the unit test to see if I could get it to match the signature. This didn't help.

Any thoughts on how I can get this to work?


Solution

  • Note that Logger is an interface, and that LogClass1 obtains an instance of it through the LogManager.getLogger static factory method. So, obviously, it creates an instance of some Logger implementation class. And said class is not being mocked in the test.

    What the test needs to do is to mock LogManager, so it returns the @Mocked Logger instance. That is, add a @Mocked LogManager field to the test class.

    (Also, no need for that setup method since @Tested creates an instance automatically.)