集成测试基于Spring Boot的微服务
我已经阅读了许多有关使用Spring Boot和RESTful服务的指南,其中许多包含有关运行单元测试的信息,最著名的是使用Spring Boot构建应用程序".但是,我还没有看到任何有关如何对消耗/依赖于其他Spring Boot应用程序的Spring Boot应用程序进行单元测试的示例,这在云微服务架构中很常见.因此,例如,我们有以下Spring Boot服务:
I have read many of the guides about working with Spring Boot and RESTful services, and many of them contain information about running unit tests, most notably "Building an Application with Spring Boot". However, I haven't seen anything that gives an example on how to unit test a Spring Boot application that consumes/depends on other Spring Boot applications, as is common in cloud micro-services architecture. So, for example, we have the following Spring Boot services:
ServiceMediator, 适配器1, 适配器2
ServiceMediator, Adapter1, Adapter2
ServiceMediator调用Adapter1或Adapter2,具体取决于输入.
ServiceMediator calls Adapter1 or Adapter2, depending on the input.
在Spring JUnit测试中启动和测试ServiceMediator之前,是否有办法启动Spring Boot服务Adapter1和Adapter2?
Is there a way to start up the Spring Boot services Adapter1 and Adapter2 before starting and testing the ServiceMediator in a Spring JUnit test?
process-exec-maven -plugin 可能会有所帮助,因为它允许在 pre-integration-test 阶段(作为标准的Spring Boot应用程序)启动多个Java进程,并自动负责在集成后测试阶段.
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.
注意:集成测试应该在 integration-test 阶段运行,因为 maven-failsafe-plugin 应该配置为 spring-boot-maven-plugin 请参阅默认生命周期
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.
以下maven(pom.xml)配置对我有用:
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>
在 test.java 文件夹中具有集成测试类( WebServerIT ):
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());
}
}