Unni Kris
Unni Kris

Reputation: 3095

Mock legacy Static method with nested calls

How to mock a method like the one below:

LoggerUtil.getInstance().getAppLog().info("Some log statement");

Here the LoggerUtil is instantiated in a static way, though the loggers are injected into this call via spring.

<bean id="LoggerUtil" class="util.LoggerUtil" factory-method="getInstance">
    <property name="appLog" ref="AppLogger" />
</bean>
<bean id="AppLogger" class="org.apache.log4j.Logger" factory-method="getLogger">
    <constructor-arg value="logging.AppLogger" />
</bean>

I have tried the below code but to no avail:

@Test
public void testLoggerUtil() {

  PowerMockito.mockStatic(LoggerUtil.class);
  LoggerUtil logUtil = mock(LoggerUtil.class);
  Logger logger = mock(Logger.class);

  PowerMockito.when(LoggerUtil.getInstance()).thenReturn(logUtil);
  when(logUtil.getAppLog()).thenReturn(logger);
  Mockito.doNothing().when(logger).info(any(String.class));

  LoggerUtil.getInstance().getAppLog().info("Some log");

}

The code is legacy and the log statement is present in thousands of places. Making any changes to it is not possible.

Any help will be highly appreciated. Thanks in Advance.

Upvotes: 0

Views: 189

Answers (1)

dsinczak
dsinczak

Reputation: 217

Maybe it is worth trying AspectJ. You can try creating aspect execued during test phase that finds pointcut LoggerUtil.getInstance() and returns some mock, or test implementation. This way you won't have to deal with logger each time you create test for legacy code.

Upvotes: 1

Related Questions