【问题标题】:spring-boot-starter-test with JUnit 5使用 JUnit 5 的 spring-boot-starter-test
【发布时间】:2019-03-22 13:46:28
【问题描述】:

从 2.0.6 开始使用 spring-boot-starter-test 会引入 JUnit 4 依赖项。如何使用 spring-boot-starter-test(通过 Gradle),但使用 JUnit 5,而不引入 JUnit 4 依赖项?

如果有帮助,这里是 Gradle 的依赖输出的一部分:

+--- org.springframework.boot:spring-boot-starter-test -> 2.0.5.RELEASE
|    +--- org.springframework.boot:spring-boot-starter:2.0.5.RELEASE (*)
|    +--- org.springframework.boot:spring-boot-test:2.0.5.RELEASE
|    |    \--- org.springframework.boot:spring-boot:2.0.5.RELEASE (*)
|    +--- org.springframework.boot:spring-boot-test-autoconfigure:2.0.5.RELEASE
|    |    +--- org.springframework.boot:spring-boot-test:2.0.5.RELEASE (*)
|    |    \--- org.springframework.boot:spring-boot-autoconfigure:2.0.5.RELEASE (*)
|    +--- com.jayway.jsonpath:json-path:2.4.0
|    |    +--- net.minidev:json-smart:2.3
|    |    |    \--- net.minidev:accessors-smart:1.2
|    |    |         \--- org.ow2.asm:asm:5.0.4
|    |    \--- org.slf4j:slf4j-api:1.7.25
|    +--- junit:junit:4.12
|    |    \--- org.hamcrest:hamcrest-core:1.3


这是我的 build.gradle 文件:

buildscript {
    ext {
        springBootVersion = '2.0.6.RELEASE'
    rootGradleDir = "${rootProject.rootDir}/gradle"
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

apply from: "${rootGradleDir}/staticCodeAnalysis.gradle"

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

test {
  useJUnitPlatform()
}

dependencies {
    implementation('org.springframework.boot:spring-boot-starter-data-jpa')
    implementation('org.springframework.boot:spring-boot-starter-jdbc')
    implementation('org.springframework.boot:spring-boot-starter-security')
    implementation('org.springframework.boot:spring-boot-starter-thymeleaf')
    implementation('org.springframework.boot:spring-boot-starter-validation')
    implementation('org.springframework.boot:spring-boot-starter-web')
    implementation('org.liquibase:liquibase-core')
    runtimeOnly('org.springframework.boot:spring-boot-devtools')
  runtimeOnly('org.postgresql:postgresql')
  testImplementation('org.springframework.boot:spring-boot-starter-test')
  testImplementation('org.springframework.security:spring-security-test')

  implementation('org.glassfish.jaxb:jaxb-runtime:2.3.1')
  implementation('org.glassfish.jaxb:jaxb-runtime2.3.1')
  implementation('org.springframework.boot:spring-boot-starter-data-redis')

  testCompile('org.junit.jupiter:junit-jupiter-api:5.3.1')
  testCompile('org.junit.jupiter:junit-jupiter-params:5.3.1')
  testRuntime('org.junit.jupiter:junit-jupiter-engine:5.3.1')
}

更新

添加 JUnit 5 依赖项并执行 cmets 中提到的排除操作就成功了。测试依赖现在看起来像这样:

testImplementation('org.springframework.boot:spring-boot-starter-test') {
    exclude group: 'junit', module: 'junit' //by both name and group
}

【问题讨论】:

  • 检查这个dzone.com/articles/…。你只需要排除junit 4
  • @lealceldeiro 刚刚试了一下,确实有效。谢谢!

标签: java spring spring-boot junit


【解决方案1】:

对其他贡献者提到的一些补充说明:

使用 Spring Boot > 2.4.0

如果您正在使用 Spring Boot > 2.4.0,那么您无需执行任何操作即可使用 JUnit 5 Jupiter,因为 spring-boot-starter-test 库不再包含 Vintage-engine 依赖项(可传递地包含 JUnit 4),只需将启动器依赖项包含到项目中就可以了。在 Gradle 配置中使用 useJUnitPlatform()

使用 2.4.0 > Spring Boot > 2.2.0

如果您使用早期版本,我建议使用高于 2.2.0.RELEASE 的版本,这是 Spring 团队默认将 JUnit 5 Jupiter 支持添加到 spring-boot-starter-test 的地方。

在这些版本中,该库还包含 Vintage Engine 依赖项,可用于使用 JUnit 5 Jupiter 平台运行 JUnit 4 测试。如果您不需要执行 JUnit 4 测试,那么 Spring 团队建议排除 org.junit.vintage:junit-vintage-engine(不仅仅是描述中指出的 junit):

testCompile('org.springframework.boot:spring-boot-starter-test') {
    exclude group: 'org.junit.vintage'
}

当然,您还需要在这里配置useJUnitPlatform() 指令。

【讨论】:

    【解决方案2】:

    这里使用实现而不是编译

    test {
      useJUnitPlatform()
    }
    
    dependencies {
        testImplementation('org.springframework.boot:spring-boot-starter-test') {
            exclude group: 'junit', module: 'junit'
        }
        testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.2'
        testImplementation 'org.junit.jupiter:junit-jupiter-params:5.4.2'
        testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.2'
    }
    

    2020 年 10 月 29 日更新

    在我们的 Spring Boot 2.3 项目中,我们不再需要这个 sn-p。默认情况下它已经在使用 JUnit 5。

    【讨论】:

      【解决方案3】:

      只需添加

      testImplementation('org.springframework.boot:spring-boot-starter-test') {
          exclude group: 'junit', module: 'junit'
      }
      testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2'
      

      还有:

      test {
          useJUnitPlatform()
      }
      

      【讨论】:

        【解决方案4】:

        似乎较新版本的 spring-boot-starter-test(在 2.2.6/2.2.7 中注意到)正在导入 org.junit.vintage:junit-vintage-engine,它对 junit:junit 具有传递依赖。 仅排除 junit 给了我一些虚假错误:

        May 13, 2020 9:20:05 AM org.junit.platform.launcher.core.DefaultLauncher handleThrowable
        WARNING: TestEngine with ID 'junit-vintage' failed to discover tests
        java.lang.NoClassDefFoundError: junit/runner/Version
        ...
        Caused by: java.lang.ClassNotFoundException: junit.runner.Version
        ...
        

        设置:

        testCompile('org.springframework.boot:spring-boot-starter-test') {
            exclude group: 'org.junit.vintage'
        }
        

        为我成功了,所有测试都继续正常运行

        【讨论】:

          【解决方案5】:

          十个月后,使用Gradle 5.4.1Spring Boot 2.1.7.RELEASEJUnit 5.5.1,我发现我使用的依赖项与其他答案不同。此外,我发现最好包含聚合工件而不是单个工件:

          testImplementation('org.junit.jupiter:junit-jupiter:5.5.1')
          

          您可以从我的另一个 SO Q&A 中了解更多关于我的观察:Interaction between Spring Boot and JUnit 5 — must use the overall artifacts not the individuals?

          【讨论】:

            【解决方案6】:

            从 Gradle 4.6 开始(我相信),有原生的 JUnit 5 支持。您可以按如下方式包含 JUnit5:

            dependencies {
              testCompile "org.junit.jupiter:junit-jupiter-api:5.2.0"
              testCompile "org.junit.jupiter:junit-jupiter-params:5.2.0"
              testRuntime "org.junit.jupiter:junit-jupiter-engine:5.2.0"
            }
            

            您还需要:

            test {
              useJUnitPlatform()
            }
            

            JUnit 4 和 5 使用不同的包名,因此它们可以共存于同一个项目中。许多注释都是相同的(@Test 等),因此请确保将它们包含在 org.junit.jupiter.api 包中。

            【讨论】:

            • 谢谢。我也这样做了,但 JUnit 4 依赖项仍然存在。听起来@lealceldeiro 提到的排除路由是这里的方法。
            • 正确,如果您根本不想包含它,则需要排除它。
            猜你喜欢
            • 2020-07-09
            • 2020-07-21
            • 2017-03-22
            • 1970-01-01
            • 2021-01-22
            • 2019-10-28
            • 2014-04-07
            • 2017-07-30
            • 2016-01-29
            相关资源
            最近更新 更多