添加到 dependencyManagement 时,SpringBoot 不会 运行 单元测试

SpringBoot does not run unit tests when added into dependencyManagement

我的项目应该是从自定义父项目继承的,同时使用 Spring Boot。 标准解决方案是使用 <dependencyManagement> 部分,如 here.

所述

问题是当 Spring Boot 依赖项添加到该部分时,maven 没有看到任何单元测试(测试 运行s = 0)。我用工件 spring-boot-dependenciesspring-boot-starter.

复制了它

重现步骤:

  1. 创建一个包含一个单元测试的 maven 项目 SampleTest 和以下 pom。
  2. 运行 mvn test.
  3. 看到 SampleTest 有 运行 和失败
  4. 取消注释 <dependencyManagement> 中的块以导入 Spring Boot
  5. 运行 mvn test
  6. 看到没有测试运行并且构建成功。

我在 surefire 的旧版本中遇到了类似的问题,它无法以类似的方式找到 JUnit5 测试。但是有效的 pom 显示在这种情况下插件的版本被正确设置为 3.0.0-M4 并且没有被 SpringBoot 覆盖。

你能帮我解决 运行ning 测试的问题并在这种情况下正确应用 Spring Boot 吗?


src/test/java/org/example/SampleTest.java

package org.example;

import org.junit.jupiter.api.*;

class SampleTest{
    @Test
    void test(){
        Assertions.assertEquals(0, 1);
    }
}

pom.xml

The following sample does not have a parent: I've just copied plugins and dependencies from that to keep it concise.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>spring-boot-import</artifactId>
    <version>1.0</version>

    <dependencyManagement>
    <!-- when this block is uncommented no unit tests are found in the project-->

    <!--
        <dependencies>
          <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.2.5.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
          </dependency>
        </dependencies>
    -->
    </dependencyManagement>

    <properties>
        <version.java>11</version.java>
        <version.junit.jupiter>5.6.0</version.junit.jupiter>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <compilerVersion>${version.java}</compilerVersion>
                    <release>${version.java}</release>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M4</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>3.0.0-M4</version>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${version.junit.jupiter}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

包含 spring-boot-dependencies 依赖项会更改 junit-jupiter-engine 依赖项的传递依赖项。

mvn dependency:tree 的输出将显示这一点。

之前

[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ spring-boot-import ---
[INFO] org.example:spring-boot-import:jar:1.0
[INFO] \- org.junit.jupiter:junit-jupiter-engine:jar:5.6.0:test
[INFO]    +- org.apiguardian:apiguardian-api:jar:1.1.0:test
[INFO]    +- org.junit.platform:junit-platform-engine:jar:1.6.0:test
[INFO]    |  +- org.opentest4j:opentest4j:jar:1.2.0:test
[INFO]    |  \- org.junit.platform:junit-platform-commons:jar:1.6.0:test
[INFO]    \- org.junit.jupiter:junit-jupiter-api:jar:5.6.0:test

之后

[INFO] org.example:spring-boot-import:jar:1.0
[INFO] \- org.junit.jupiter:junit-jupiter-engine:jar:5.6.0:test
[INFO]    +- org.apiguardian:apiguardian-api:jar:1.1.0:test
[INFO]    +- org.junit.platform:junit-platform-engine:jar:1.5.2:test
[INFO]    |  +- org.opentest4j:opentest4j:jar:1.2.0:test
[INFO]    |  \- org.junit.platform:junit-platform-commons:jar:1.5.2:test
[INFO]    \- org.junit.jupiter:junit-jupiter-api:jar:5.5.2:test

如您所见,junit-platform-engine 和朋友从 1.6.0 更改为 1.5.2 并且 API 从 5.6.05.5.2。由于这些 jar 是不兼容的版本,因此您的测试将不再 运行。

要修复,您可以执行以下操作之一

  1. 添加所有附加的、可传递的、具有显式版本的依赖项
  2. junit-bom 也添加到 Spring 启动前的 dependencyManagement 部分,以强制版本
  3. 降级到 JUnit 5.5.2 以与 Spring 引导管理版本
  4. 保持一致

另一个解决方案是在 spring 引导之前简单地定义 junit jupiter 的导入。这也解决了这个问题。

  <dependencyManagement>
    <dependencies>    
      <dependency>
        <groupId>org.junit</groupId>
        <artifactId>junit-bom</artifactId>
        <version>5.6.0</version>
        <scope>import</scope>
        <type>pom</type>
      </dependency>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>2.2.5.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

如果你使用的是Spring Boot 2.x那么默认情况下它支持JUnit 5并且所有在JUnit 4中编写的测试用例在构建项目或执行时都不会被读取[=14] =] 测试。 要修复它,请使用 pom.xml 中的以下代码段:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.8</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven.surefire</groupId>
            <!-- Use the older JUnit 4 provider -->
            <artifactId>surefire-junit4</artifactId>
            <version>2.8</version>
        </dependency>
    </dependencies>
</plugin>

注意:使用上面的方法将跳过您的 JUnit 5 测试用例。