0

I have done a fair amount of research and don't see a good way to do this. I have a java application that has integration tests. For the sake of the integration tests, the tests need to start the actual application. This is done like so in each junit test.

@BeforeClass
final public static void setup() {
    Application.main(new String[]{});
}

How do I shut down the application though? I notice it stays around as rogue process after the junit tests shutdown. In addition I have done this with springboot before and am aware that springboot provides annotations. We cannot use springboot though for this. So i need to find a non spring way. How do I shut down the application in a junit test?

slipperypete
  • 5,358
  • 17
  • 59
  • 99

1 Answers1

0

I cannot reproduce this with Gradle 6.3 and JUnit 5; I briefly see a [java] <defunct> process in the ps output, and that disappears on its own. Maybe it's because I only run a single test suite and when you run more you'd need to cleanup after each.

That said, look into the Java process API. Start the app as in this question, but hold on to the Process returned from ProcessBuilder.start() and call its destroy() method in your @AfterClass method.

package com.example.demo;

import java.util.ArrayList;
import org.junit.jupiter.api.*;

public class DemoApplicationTests {
    private static Process process;

    @BeforeAll
    public static void beforeClass() throws Exception {
        ArrayList<String> command = new ArrayList<String>();
        command.add(System.getProperty("java.home") + "/bin/java"); // quick and dirty for unix
        command.add("-cp");
        command.add(System.getProperty("java.class.path"));
        command.add(DemoApplication.class.getName());

        ProcessBuilder builder = new ProcessBuilder(command);
        process = builder.inheritIO().start();
    }

    @Test
    void whatever() {
        // ...
    }

    @AfterAll
    public static void afterClass() {
        process.destroy();  
    }
}
Robert
  • 7,394
  • 40
  • 45
  • 64
  • Woah my mind is a little blown right now ... Im going to mark this with a green checkmark, but I would really be interested if anybody else has solutions to this. Thanks. – slipperypete May 06 '20 at 00:14
  • This is a solid answer and I got this working. However I noticed afterwards I didn't actually need to do this. The reason being that if you start the application with Appliation.main() ... It will start and stop within the junit tests. I was mislead because when I was looking at the processes. When starting the integration tests, I noticed 2 would start up and 1 would remain after. I assumed this was the one that was started with Application.main() ... When I executed the other junit tests though, i notice that they too start a process that is not terminated after the tests are done ‍♂️. – slipperypete May 06 '20 at 18:22