maven - 使用 docker 容器的 Spring Boot 集成测试多模块 maven 应用程序
问题描述
我有一个使用 Spring Boot 的多模块 Maven 应用程序。它定义了 Rest API 来为消费者提供服务。
- 弹簧靴父
- myproject 父级(父级和模块 pom)
- 模块1
- module-it(集成测试)
- myproject 父级(父级和模块 pom)
在我的模块 1 中 pom 中的 Spring boot maven 插件配置如下
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.4.RELEASE</version>
<configuration>
<mainClass>com.package.Application</mainClass>
<layout>JAR</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
我正在使用 fabric io 创建 docker 映像。见下文我的模块 1 中的 fabric io 插件定义
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.24.0</version>
<configuration>
<images>
<image>
<alias>service</alias>
<name>Sample</name>
<build>
<from>greyfoxit/alpine-openjdk8</from>
<entryPoint>
<exec>
<arg>java</arg>
<arg>-jar</arg>
<arg>maven/sample-model-1.0.0-SNAPSHOT.jar</arg>
</exec>
</entryPoint>
<assembly>
<descriptorRef>artifact-with-dependencies</descriptorRef>
</assembly>
<ports>
<port>8080</port>
</ports>
</build>
</image>
</images>
</configuration>
<executions>
<execution>
<id>docker-build</id>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
在 Spring boot maven 插件中添加了分类器配置作为集成测试模块的 exec,以识别要引导的 Spring boot 应用程序类。
在我的集成测试模块中,我使用故障安全插件进行集成测试。有关集成测试模块中的插件定义,请参见下文
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18.1</version>
<executions>
<execution>
<id>integration-tests</id>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<includes>
<include>**/*.java</include>
</includes>
<groups>io.sample.test.IntegrationTest</groups>
<skipTests>${skip.integration.tests}</skipTests>
</configuration>
</execution>
</executions>
</plugin>
我的 IntegrationTest 类定义如下。
@RunWith(SpringRunner.class)
@Category(IntegrationTest.class)
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ControllerIT
{
@Autowired
private MockMvc mockMvc;
@Autowired
private Environment env;
@Test
public void IntegrationTestForService() throws Exception {
JsonNode node=mapper.readTree(new File("/src/integration-test/resources/Request.json"));
RequestBuilder requestBuilder = MockMvcRequestBuilders
.post("/api/sample/v1")
.accept(MediaType.APPLICATION_JSON).content(node.toString())
.contentType(MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(requestBuilder).andReturn();
MockHttpServletResponse response = result.getResponse();
assertEquals(HttpStatus.CREATED.value(), response.getStatus());
}
}
IntegrationTest 执行良好并且能够测试 REST API。但是,当我尝试使用 docker run 使用 module1 jar 文件运行 docker 文件时,spring boot 没有启动。它说未找到清单。下面是错误信息。
没有主清单属性,在 maven/sample-model-1.0.0-SNAPSHOT.jar 中。
当我从模块 1 中删除 exec 分类器时,spring boot 能够在执行 docker run 命令时启动。但是,如果分类器不存在,我在使用 Spring boot Test 执行集成测试用例时遇到问题。
您能否建议是否有任何选择。
解决方案
我认为如果您要使用分类器为 Spring Boot 生成一个单独的重新打包的 jar,那么您需要在 docker-maven-plugin 配置中引用该重新打包的 jar。也就是说,您<entrypoint><exec>
应该调用 sample-model-1.0.0-SNAPSHOT-exec.jar。(注意“-exec”)
此外,为了良好的实践,您可能需要考虑为您的 jar 目标使用项目变量,而不是对版本进行硬编码,例如:
<entrypoint>
<exec>
<arg>java</arg>
<arg>-jar</arg>
<arg>maven/${project.artifactId}-${project.version}-exec.jar</arg>
</exec>
</entrypoint>
您还需要将您的程序集从带有依赖关系的工件描述符引用更改为内联程序集,以便将 jar 的“exec”版本内置到您的 Docker 映像中。(另请注意,artifact-with-dependencies 将所有这些冗余依赖项扔到您的图像中,使其比需要的更大。)
<assembly>
<inline>
<fileSets>
<fileSet>
<directory>target</directory>
<outputDirectory>.</outputDirectory>
<fileMode>0644</fileMode>
<includes>
<include>${project.artifactId}-${project.version}-exec.jar</include>
</includes>
</fileSet>
</fileSets>
</inline>
</assembly>
推荐阅读
- python - 模拟 requests.post
- node.js - 在 MongoDB 中查询嵌套在数组中的对象
- java - 我正在尝试使用休息控制器从 h2 数据库中检索记录,但它说没有数据集
- python - 如何实时更新图像文件 Pygame?
- c# - http请求不使用json格式
- python - 向具有 CSRF 保护的 Ruby on Rails 应用程序发出 POST 请求时出现 404 错误
- dataframe - 如何使用 PySpark 在数据框中过滤字符串类型的嵌套列
- python - 无法使用 beautifulsoup 抓取 div 文本
- java - 按下回车键后如何限制扫描仪对象接受任何内容
- javascript - 如何计算两个日期选择器之间的总天数并将结果显示在另一个文本字段中?