0

I have some business logic that runs when Spring boot application starts (i.e in main method)

@SpringBootApplication
@EnableGatewayService
@EnableAsync
@Slf4j
public class AuthOpsApplication {
     public static void main(String[] args) throws IOException {
        application.addListeners(new WEPFallbackListener());
        application.addListeners(new SaeListener());
        application.run(args);
        // some business logic
        log.info("logs some info of the business logic");

    }
}

I want to write a test case to check if the log.info is getting printed and its value is as expected. I do not want to test the business logic as a standalone code, I would like to run the main function and somehow read the log that it puts out, Is this possible?

What I tried:

import org.springframework.test.context.junit4.SpringRunner;
import uk.org.lidalia.slf4jtest.TestLogger;
import uk.org.lidalia.slf4jtest.TestLoggerFactory;
import org.springframework.boot.test.autoconfigure.actuate.metrics.AutoConfigureMetrics;
import org.springframework.test.context.ActiveProfiles;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = AuthOpsApplication.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.ANY)
@ActiveProfiles("test")
@AutoConfigureMetrics
public class LogTest {
    TestLogger logger = TestLoggerFactory.getTestLogger(AuthOpsApplication.class);


    @Test
    public void testAnyLog() throws IOException {
        System.out.println(logger.getLoggingEvents());

    }

    @After
    public void clearLoggers() {
        TestLoggerFactory.clear();
    }
}

This runs successfully and creates all the Beans but does not actually call the main() method of my AuthOpsApplication class.

( I can say this because the System.out.println() that I did gives all the other logs except the ones in main() method).

Thanks in advance for the help.

Faizal
  • 41
  • 6

1 Answers1

0

Your test code can do this:

  1. Apply https://stackoverflow.com/a/1119559/6944068 to capture stdout.
  2. Run what's inside AuthOpsApplication.main().
  3. Collect captured stdout until you see the expected message.
  4. Call application.close() to shut down.

Some general advice:

  • It's pretty common to do startup logging right after calling application.run, but strictly speaking that's a race condition and you don't known at what point the business info you're logging will be available. You'll be more robust if you put the logging into the beans that have that information.
  • The code as given in the question does not initialize application.
  • You don't want to copy the code for step 2 from main(), you'll want to put that into a function you can call from your test code. That function should also return application so the test code can close() it in step 4.
  • If you have more tests that require the full application, you'll want to organize them that you have application startup and shutdown only once. (I don't have recipes for that, how to do that would be food for another SO question.)
toolforger
  • 754
  • 7
  • 22