11

我已经阅读了许多有关使用 Spring Boot 和 RESTful 服务的指南,其中许多包含有关运行单元测试的信息,最值得注意的是“使用 Spring Boot 构建应用程序”。但是,我还没有看到任何示例说明如何对使用/依赖于其他 Spring Boot 应用程序的 Spring Boot 应用程序进行单元测试,这在云微服务架构中很常见。因此,例如,我们有以下 Spring Boot 服务:

服务中介、适配器 1、适配器 2

ServiceMediator 调用 Adapter1 或 Adapter2,具体取决于输入。

有没有办法在 Spring JUnit 测试中启动和测试 ServiceMediator 之前启动 Spring Boot 服务 Adapter1 和 Adapter2?

4

2 回答 2

7

process-exec-maven-plugin可能会有所帮助,因为它允许在预集成测试阶段启动多个 Java 进程(作为标准 Spring Boot 应用程序),并且它会在集成测试后阶段自动关闭它们.

注意:集成测试应该在集成测试阶段运行,因为maven-failsafe-plugin应该配置为spring-boot-maven-plugin 请参阅。然后运行我们的集成测试verify或更高级别的 maven Lifecycle 应该是目标,因为集成测试阶段实际上位于 packageverify Lifecycles之间,请参阅 Default Lifecycles

以下 maven (pom.xml) 配置对我有用:

<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>

在test.java文件夹中有一个集成测试类(WebServerIT):

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());
    }
}
于 2016-05-23T18:12:34.333 回答
1
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();
        }
    }
}
于 2015-04-20T21:40:22.947 回答