1

I'm attempting to figure out how to test a method written in my LoggingRestService class. I'd like to verify that my (external) error method produces the correct log entry in this logger.

private static final Logger LOGGER = LoggerFactory.getLogger(LoggingRestService.class);

@POST
@Path("debug")
@ApiOperation(value = "Writes js error message log. (not secured)")
@ApiResponse(code = 200, message = "Message logged")
public void getUserList(@ApiParam(value = "Js debug message.")
                                String message) {
    ConverterUtils.error(LOGGER, message, null);
}

}

Here is ConverterUtils error method:

public static void error(Logger logger, String mess, Exception ex) {
    Class<?> aClass = logger.getClass();
    try {
        Method method = aClass.getMethod("error", String.class, Throwable.class);
        method.invoke(logger, mess, ex);
    } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
        LOGGER.error("get logger error", e);
    }
}

I've never used mockito but I am somewhat familiar with the concept of mocking classes..still I'm a little boggled. I was not given much direction for testing and attempting to be self sufficient is slowly rotting my confidence. Thanks a bunch.

jubilantdollop
  • 223
  • 3
  • 11
  • see http://stackoverflow.com/questions/30703149/mock-private-static-final-field-using-mockito-or-jmockit – paulk23 Jun 29 '16 at 21:46
  • Nice to see somebody testing logging. I have been (on and off) writing a library to help with testing logging based in part on this http://bloodredsun.com/2010/12/09/checking-logging-in-unit-tests/ Its a nice description of how to test logging. Maybe it would help. (looking at google, there are several articles on testing logging) – Gavin Jun 29 '16 at 22:53

1 Answers1

1

Let me check if I get what you are saying: you want to verify that your ConverterUtil class is calling the error method with the appropriate message and exception right.

To be able to do that you would need to make sure that your ConverterUtils class is called with a mock version of a Logger. You can do that with mock(Logger.class). That will work even if Logger is a class and not an interface because Mockito can mock classes that are not final. It will actually create a subclass for you.

Your test code will look:

Logger mockedLogger = mock(Logger.class);
String expectedMessage = "Whatever";
Exception expectedException = new Exception();

// Business method
ConverterUtils.error(mockedLogger, expectedMessage, expectedException);

// Asserts
verify(mockedLogger).error(expectedMessage, expectedException);

On a side node: it puzzles me why the error method is not as simple as:

public static void error(Logger logger, String mess, Exception ex) {
    logger.error(mess, ex);
}

I really don't see why you need to use the reflection layer here. You know exactly what method you want, so why don't you simply invoke the method as is.