Integration testing Spring Boot based Microservices

穿精又带淫゛_ 提交于 2019-12-01 03:34:05

The process-exec-maven-plugin could be helpful as allows to start multiple java processes at pre-integration-test phase (as standard Spring Boot apps), and it automatically takes care of shutting them down in the post-integration-test phase.

NOTE: The integration test should be run at the integration-test phase for that the maven-failsafe-plugin should be configured with spring-boot-maven-plugin see. Then to run our integration tests verify or higher maven Lifecycle should be targeted, because the integration-test phase is in fact located between package and verify Lifecycles see Default Lifecycles.

The following maven (pom.xml) configuration worked for me:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>1.3.5.RELEASE</version>
            <executions>                    
                <execution>
                    <id>pre-integration-test</id>
                    <goals>
                        <goal>start</goal>
                    </goals>
                    <configuration>
                        <skip>${integration-tests.skip}</skip>
                    </configuration>
                </execution>
                <execution>
                    <id>post-integration-test</id>
                    <goals>
                        <goal>stop</goal>
                    </goals>
                    <configuration>
                        <skip>${integration-tests.skip}</skip>
                    </configuration>
                </execution>
            </executions>
        </plugin>           

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.19.1</version>
            <configuration>
                <skip>${integration-tests.skip}</skip>                  
                <includes>
                    <include>**/*IT.java</include>
                </includes>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>                        
                </execution>                    
            </executions>
        </plugin>

        <plugin>
            <groupId>com.bazaarvoice.maven.plugins</groupId>
            <artifactId>process-exec-maven-plugin</artifactId>
            <version>0.7</version>
            <executions>                    
                <execution>
                    <id>switchboard-process</id>
                    <phase>pre-integration-test</phase>
                    <goals>
                        <goal>start</goal>
                    </goals>
                    <configuration>
                        <name>accounts-service</name>
                        <workingDir>/../../micro-service</workingDir>
                        <waitForInterrupt>false</waitForInterrupt>                          
                        <arguments>
                            <argument>java</argument>
                            <argument>-jar</argument>
                            <argument>${basedir}/../micro-service/target/micro-service-${project.version}-exec.jar</argument>
                        </arguments>
                    </configuration>
                </execution>
                <!--Stop all processes in reverse order-->
                <execution>
                    <id>stop-all</id>
                    <phase>post-integration-test</phase>
                    <goals>
                        <goal>stop-all</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Having an Integration Test class (WebServerIT) in test.java folder:

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = WebServerApp.class)
@WebIntegrationTest("server.port:0")
public class WebServerIT {

    @Autowired
    private WebApplicationContext webServerAppContext;

    private MockMvc webServerMockMvc;

    @Before
    public void setUp() {
        System.out.println("the test is set up");
        webServerMockMvc = MockMvcBuilders.webAppContextSetup(webServerAppContext).build();
    }

    /**
     * This test calls the WebServer's endpoint (/accounts/123456789) which in turn calls the micro-service rest api 
     * which is started using the process-exec-maven-plugin, otherwise the test would fail.
     */
    @Test
    public void testWebServerInteractionWithMicroService() throws Exception {
        this.webServerMockMvc.perform(get("/accounts/123456789"))
                .andExpect(status().isOk());
    }
}
package controller;


import static org.junit.Assert.assertThat;

import java.io.File;
import java.net.URL;

import mediator.CLPApplication;

import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.IntegrationTest;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = CLPApplication.class)
@WebAppConfiguration
@IntegrationTest()
public class ControllerTest {

    @Value("${adapter.dependency.jar.location}")
    private String adapterDependencyJarLocation;

    @Value("${adapter.dependency.jar.name}")
    private String adapterDependencyJarName;

    @Value("${adapter.url}")
    private String adapterURL;

    @Value("${mediator.url}")
    private String mediatorURL;

    private URL mediator;
    private URL adapter;
    private RestTemplate template;
    Process process = null;

    @Before
    public void setUp() throws Exception {

        adapter = new URL(adapterURL);
        template = new TestRestTemplate();

        //
        // Start the Atomic adapter
        // 
        System.out.println(adapterDependencyJarLocation);
        System.out.println("Starting Adapter");

        try {
            process = new ProcessBuilder("java", "-jar", adapterDependencyJarName)
                .directory(new File(adapterDependencyJarLocation)).start();

            // Try connecting 5 times with a 5 second pause between each
            // to see if it started. 
            Thread.sleep(5000);
            for(int i = 0; i <= 5; i++) {
                try{
                    System.out.println("Testing to see if Adapter is up");
                    template.getForEntity(adapter.toString(), String.class);
                    System.out.println("Adapter Started");
                    break;
                }
                catch(RestClientException rce){
                    System.out.println("It's not up yet");
                }
                Thread.sleep(5000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testMediator() throws Exception {
        mediator = new URL(mediatorURL);
        System.out.println("Calling Mediator");
        ResponseEntity<String> response = template.getForEntity(mediator.toString(), String.class);
        System.out.println(response.getBody());
        // Getting back JSON, so check to see if it starts with an open bracket
        assertThat(response.getBody(), Matchers.startsWith("{"));
    }

    @After
    public void tearDown() {
        if(process != null) {
            process.destroy();
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!