Spring 启动测试多模块 maven 应用程序
Spring boot test multimodule maven application
我有一个使用 Spring 引导的多模块 Maven 应用程序:
- spring boot parent
- myproject parent (both parent and module pom)
- module1
- module2
- module-it (integration tests)
在我的 module-it 中,我将其他模块添加到我的依赖项中,并按如下方式配置 maven-failsafe-plugin:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
当我用 maven 构建我的项目时,我得到 "Build Success":
mvn clean install
到目前为止一切顺利。
然而,我希望我的每个模块在构建结束时都是一个可执行的 jar。使用上述设置,未定义清单且 jar 不可执行。
为了解决这个问题,我在我的 module1 和 module2 pom 文件中添加了以下内容:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
使用此设置,我的 jar 文件是可执行的,但我无法再构建。 类 我在我的模块中使用的 - 未找到。
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile (default-testCompile) on project module-it: Compilation failure: Compilation failure:
[ERROR] /home/user/<path-to-project>/testing/module-it/src/test/java/com/mycompany/testing/greeting/GreetingControllerIT.java:[20,17] cannot find symbol
[ERROR] symbol: class GreetingController
[ERROR] location: class com.mycompany.testing.greeting.GreetingControllerIT
[ERROR] /home/user/<path-to-project>/testing/module-it/src/test/java/com/mycompany/testing/hello/HelloControllerIT.java:[20,17] cannot find symbol
[ERROR] symbol: class HelloController
[ERROR] location: class com.mycompany.testing.hello.HelloControllerIT
[ERROR] /home/user/<path-to-project>/testing/module-it/src/test/java/com/mycompany/testing/greeting/GreetingControllerIT.java:[16,27] cannot find symbol
[ERROR] symbol: class GreetingController
[ERROR] /home/user/<path-to-project>/testing/module-it/src/test/java/com/mycompany/testing/hello/HelloControllerIT.java:[16,27] cannot find symbol
[ERROR] symbol: class HelloController
我的测试具有以下形式(HelloControllerIT.java 同上):
@RunWith(SpringRunner.class)
@SpringBootTest(classes = GreetingController.class)
public class GreetingControllerIT {
@Autowired
private GreetingController greetingController;
@Test
public void getIT_OK() throws Exception {
Assert.assertEquals("My greetings", greetingController.getStr());
}
}
而Controllers有这样的形式(这里的getStr()方法只是为了测试配置):
@RestController
public class GreetingController {
public String getStr() {
return "My greetings";
}
@RequestMapping(value = "/greeting", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
public String get() {
return "greeting";
}
}
你能帮我理解为什么 spring-boot-maven-plugin 使我的构建失败以及我该如何解决这个问题吗?
我知道:
- 我的测试目前不是集成测试。这只是一个例子;
- 根据我在 Whosebug 上找到的答案,我可以添加一个文件,例如下面的文件,然后使用 @ContextConfiguration,但我试过了,它不会改变 Maven 构建的输出。
@Configuration
@ComponentScan(basePackages = "com.mycompany.testing")
public class AppConfig {
}
在此先感谢您的帮助。
为了解决这个问题,我们可以按照文档中的描述添加一个分类器custom repackage classifier
然后插件变成:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
您还可以将 repackage 目标参数 attach 设置为 false:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<attach>false</attach>
</configuration>
</execution>
</executions>
</plugin>
至少对于 spring-boot-starter-parent:2.6.0
pom,spring-boot-maven-plugin
的配置包含一个 <id>repackage</id>
用于执行 repackage
目标
所以我也必须添加行 <id>repackage</id>
。
完整配置:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
我有一个使用 Spring 引导的多模块 Maven 应用程序:
- spring boot parent
- myproject parent (both parent and module pom)
- module1
- module2
- module-it (integration tests)
在我的 module-it 中,我将其他模块添加到我的依赖项中,并按如下方式配置 maven-failsafe-plugin:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
当我用 maven 构建我的项目时,我得到 "Build Success":
mvn clean install
到目前为止一切顺利。
然而,我希望我的每个模块在构建结束时都是一个可执行的 jar。使用上述设置,未定义清单且 jar 不可执行。
为了解决这个问题,我在我的 module1 和 module2 pom 文件中添加了以下内容:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
使用此设置,我的 jar 文件是可执行的,但我无法再构建。 类 我在我的模块中使用的 - 未找到。
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile (default-testCompile) on project module-it: Compilation failure: Compilation failure:
[ERROR] /home/user/<path-to-project>/testing/module-it/src/test/java/com/mycompany/testing/greeting/GreetingControllerIT.java:[20,17] cannot find symbol
[ERROR] symbol: class GreetingController
[ERROR] location: class com.mycompany.testing.greeting.GreetingControllerIT
[ERROR] /home/user/<path-to-project>/testing/module-it/src/test/java/com/mycompany/testing/hello/HelloControllerIT.java:[20,17] cannot find symbol
[ERROR] symbol: class HelloController
[ERROR] location: class com.mycompany.testing.hello.HelloControllerIT
[ERROR] /home/user/<path-to-project>/testing/module-it/src/test/java/com/mycompany/testing/greeting/GreetingControllerIT.java:[16,27] cannot find symbol
[ERROR] symbol: class GreetingController
[ERROR] /home/user/<path-to-project>/testing/module-it/src/test/java/com/mycompany/testing/hello/HelloControllerIT.java:[16,27] cannot find symbol
[ERROR] symbol: class HelloController
我的测试具有以下形式(HelloControllerIT.java 同上):
@RunWith(SpringRunner.class)
@SpringBootTest(classes = GreetingController.class)
public class GreetingControllerIT {
@Autowired
private GreetingController greetingController;
@Test
public void getIT_OK() throws Exception {
Assert.assertEquals("My greetings", greetingController.getStr());
}
}
而Controllers有这样的形式(这里的getStr()方法只是为了测试配置):
@RestController
public class GreetingController {
public String getStr() {
return "My greetings";
}
@RequestMapping(value = "/greeting", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
public String get() {
return "greeting";
}
}
你能帮我理解为什么 spring-boot-maven-plugin 使我的构建失败以及我该如何解决这个问题吗?
我知道:
- 我的测试目前不是集成测试。这只是一个例子;
- 根据我在 Whosebug 上找到的答案,我可以添加一个文件,例如下面的文件,然后使用 @ContextConfiguration,但我试过了,它不会改变 Maven 构建的输出。
@Configuration
@ComponentScan(basePackages = "com.mycompany.testing")
public class AppConfig {
}
在此先感谢您的帮助。
为了解决这个问题,我们可以按照文档中的描述添加一个分类器custom repackage classifier
然后插件变成:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
您还可以将 repackage 目标参数 attach 设置为 false:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<attach>false</attach>
</configuration>
</execution>
</executions>
</plugin>
至少对于 spring-boot-starter-parent:2.6.0
pom,spring-boot-maven-plugin
的配置包含一个 <id>repackage</id>
用于执行 repackage
目标
所以我也必须添加行 <id>repackage</id>
。
完整配置:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>