Maven Spring Boot插件:如何从另一个项目中运行Spring Boot

11

https://docs.spring.io/spring-boot/docs/current/maven-plugin/usage.html

我有一个项目,包含2个模块。

[Parent]  
|-pom.xml
|  [SpringBoot2App]  
|  |-pom.xml  
|  [test]  
|  |-pom.xml  (start goal here!)

我想在另一个模块中运行集成测试(使用Maven Failsafe插件)。

是否可以配置Spring Boot Maven插件,在父模块的集成测试期间启动/停止子模块?

我尝试过类似以下的一些操作,但没有成功:

        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>

            <configuration>

                <mainClass>com.SimpleServiceApplication</mainClass>
                <classesDirectory>../SpringBoot2App/target/classes</classesDirectory>
                <folders>
                     <param>../SpringBoot2App/target/test-classes</param>
                </folders>

            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>start</goal>
                    </goals>
                    <phase>pre-integration-test</phase>
                </execution>
            </executions>
        </plugin>

不起作用。

我也尝试了在阅读插件的超类源代码https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java后添加“project”参数。

            <configuration> 
                <mainClass>com.SimpleServiceApplication</mainClass>
                <project>${project.parent.collectedProjects[0]}</project>
            </configuration>

这指的是正确的项目,但调试显示也不起作用。

请不要评论[0],我知道[0]不干净,并且是一种耦合,需要直接了解父pom模块排序的知识。

我在org/springframework/boot/SpringApplication上得到了java.lang.NoClassDefFoundError错误。

我将starter-web项目添加到测试pom.xml中,结果相同。

2个回答

9
我认为使用 spring-boot-maven-plugin 并不能对另一个模块进行集成测试,因为 start 目标似乎没有提供一种从本地存储库或 Maven 反应堆解析应用程序的方法,这可能是您想要的。您尝试过的 project 配置属性不是设计成以这种方式被覆盖的。插件执行应仅使用插件目标 文档 中列出的属性进行配置。
相反,我认为您至少有两种可能的方法:
1. 使用不同的插件来控制服务器;或
2. 直接在代码测试中运行服务器。
选项 1:
对于此选项,我认为您需要一种方法,将您想要运行的服务器构件复制到其中,并配置一些更通用的内容来启动和停止它,例如 cargo-maven2-pluginprocess-exec-maven-plugin
只需在服务器构建中配置 repackage 目标即可:
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <excludeDevtools>true</excludeDevtools>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

然后从集成测试模块开始,你可以做如下操作:

<plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-server-artifact</id>
            <goals>
                <goal>copy</goal>
            </goals>
            <phase>pre-integration-test</phase>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>SpringBoot2App</artifactId>
                        <version>${project.version}</version>
                        <classifier>jar</classifier>
                        <outputDirectory>${project.build.directory}</outputDirectory>
                        <destFileName>app.jar</destFileName>
                    </artifactItem>
                </artifactItems>
            </configuration>
        </execution>
    </executions>
</plugin>

<plugin>
    <groupId>com.bazaarvoice.maven.plugins</groupId>
    <artifactId>process-exec-maven-plugin</artifactId>
    <version>0.7</version>
    <executions>
        <execution>
            <id>start-server</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>start</goal>
            </goals>
            <configuration>
                <name>run-server</name>
                <waitForInterrupt>false</waitForInterrupt>
                <healthcheckUrl>http://localhost:8080</healthcheckUrl>
                <arguments>
                    <argument>java</argument>
                    <argument>-jar</argument>
                    <argument>${project.build.directory}/app.jar</argument>
                </arguments>
            </configuration>
        </execution>

        <execution>
            <id>stop-server</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>stop-all</goal>
            </goals>
        </execution>
    </executions>
</plugin>

选项2

在测试工件中声明对服务器工件的普通Maven依赖项,并在JUnit before hook或其他位置运行服务器的@SpringBootApplication类,例如:

private static ConfigurableApplicationContext context;

@BeforeClass
public static void setUp() {
    context = new SpringApplicationBuilder(SimpleServiceApplication.class).run();
}

@AfterClass
public static void tearDown() {
    if (context != null) {
        context.close();
    }
}

这可能已经足够满足你的需求了。

3

RyanP的解决方案完全符合需求。

但是,出于幸运的原因,我成功地让它工作了 :)

  1. 需要在TEST模块中重新添加用于运行应用程序所需的依赖项。(在此情况下为spring-boot.starter-web)

  2. 添加测试类需要一个非常有趣的语法

到目前为止,优点是我可以在运行服务器的同时对其进行测试,同时还可以使用配置文件和服务的测试类来模拟一些服务。

老实说,我仍然会尝试上述两种解决方案,但只是为了展示,这就是我最终得到的结果。

        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>

            <executions>
                <execution>
                    <id>start-mocked-app</id>
                    <configuration>

                        <arguments>
                            <argument>--server.port=${tomcat.http.port}</argument>
                        </arguments>

                        <mainClass>xxx.TestApplication</mainClass>
                        <classesDirectory>../${api-module}/target/classes</classesDirectory>

                        <folders>
                            <!-- wow! notice the weird "./" rather than the expected "../" -->
                            <folder>./${api-module}/target/test-classes</folder>
                        </folders>


                        <profiles>
                            <profile>MOCKED</profile>
                        </profiles>

                    </configuration>
                    <goals>
                        <goal>start</goal>
                    </goals>
                    <phase>pre-integration-test</phase>
                </execution>

                <execution>
                    <id>stop</id>

                    <goals>
                        <goal>stop</goal>
                    </goals>
                    <phase>post-integration-test</phase>
                </execution>
            </executions>
        </plugin>

并且...

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <scope>provided</scope>
    </dependency>
    <!-- ... -->
</dependencies>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接