1
votes

I have a spring boot project with two apps, one in src/test and one in src/main. I have two apps, one mediator to connect with a SOAP endpoint and one acting as a mock server for testing.

I have an integration test checking if it will hit ( requires test app(port 9119) and main app(port 28433) to be up)

I used maven spring boot plugin to configure to run both apps like this in my POM and also made it skip unit test when running mvn verify.

<plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
             <includePom>true</includePom>          
        </configuration>  
            <executions>
                <execution>
                    <id>pre-integration-test</id>
                    <goals>
                        <goal>start</goal>
                    </goals>
                    <configuration>
               <mainClass>com.nulogix.billing.App</mainClass>   
                    </configuration> 

                </execution>
                <execution>
                    <id>pre-integration-test2</id>
                    <goals>
                        <goal>start</goal>
                    </goals>
                    <configuration>
               <mainClass>com.nulogix.billing.mockserver.MockServerApp</mainClass>   
                    </configuration> 

                </execution>
                <execution>
                    <id>post-integration-test</id>
                    <goals>

                         <goal>stop</goal>                  
                    </goals>
                     <configuration>
               <mainClass>com.nulogix.billing.App</mainClass>   
                    </configuration>

                </execution>
                <execution>
                    <id>post-integration-test2</id>
                    <goals>

                         <goal>stop</goal>                  
                    </goals>
                     <configuration>
               <mainClass>com.nulogix.billing.mockserver.MockServerApp</mainClass>   
                    </configuration>

                </execution>
            </executions>

        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.18.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M3</version>
    <configuration>
        <skipTests>true</skipTests>
    </configuration>
</plugin>

When I run mvn verify it loads 28433 in pre-integration phase but when it try to run 9119 in pre-integration phase 2 it gives this error:

java.lang.ClassNotFoundException: com.nulogix.billing.mockserver.MockServerApp
    at java.net.URLClassLoader.findClass (URLClassLoader.java:436)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:588)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:521)
    at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run (AbstractRunMojo.java:553)
    at java.lang.Thread.run (Thread.java:835)

The class path directory is right. I tried adding a class scope in my pom to it but it didn't seem to fix the issue and gave me the same error.

In the post-integration phase when it shuts down it gives this error which I assume just means it couldn't load the application context hence there is no bean found to shut it down

Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.1.0.RELEASE:stop (post-integration-test2) on project billing_mediator: Spring application lifecycle JMX bean not found (fork is null). Could not stop application gracefully: org.springframework.boot:type=Admin,name=SpringApplication -> [Help 1]

When I run mvn -x for stack trace it automatically gives me a build failure and gives me this

org.apache.maven.lifecycle.NoGoalSpecifiedException: No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy.

Is this implying I have my POM setup wrong?

1
WIll it be ok if only keep one pair of start/stop ? for example only for com.nulogix.billing.mockserver.MockServerApp - Qingfei Yuan
@QingfeiYuan I also need my main app to run to successfully connect to soap endpoint when integration testing. - schooner_101
I know that. Just want to know if it is the root cause. If it is, We can have other workaround. - Qingfei Yuan
@QingfeiYuan Ah okay then yeah.It successfully starts on 28433 with just that port in integration phase - schooner_101
if this plugin confirmed only allow one pair of start/stop. Then you have two merge 2 start into 1. The same to stop. I think. - Qingfei Yuan

1 Answers

1
votes

I got this to work by adding only one integration phase with my Main app since maven does not scan the src/test folder. I then created application context of my mock server and made it run before the test class.

<plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
            <mainClass>com.nulogix.billing.App</mainClass> 
        </configuration>
            <executions>
                <execution>
                    <id>pre-integration-test</id>
                    <goals>
                        <goal>start</goal>
                    </goals>
                </execution>
                <execution>
                    <id>post-integration-test</id>
                    <goals>
                        <goal>stop</goal>
                    </goals>
                </execution>
            </executions>

        </plugin>
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {EndPointTestConfiguration.class
})


public class SoapIT {
private static ApplicationContext context;
    @BeforeClass
    static public void  setup(){
        SpringApplication springApplication = new SpringApplicationBuilder()           
                .sources(MockServerApp.class)
                .build();
        context = springApplication.run();
    }


    @Autowired
    private String studyDetailDemo;
    @Test
    public void soapTest() throws ClientProtocolException, IOException {
        String result = Request.Post("https://127.0.0.1:28433/nulogix/ws/billingtool")
                .connectTimeout(2000)
                .socketTimeout(2000)
                .bodyString("testing", ContentType.TEXT_PLAIN)
                .execute().returnContent().asString();

    }
}

This will make my main app run pre-integration test and then launch my mockserver app before the test runs. Thus this launches both apps before the integration test and hits my soap call.