使用 JUnit 5 的 spring-boot-starter-test
Posted
技术标签:
【中文标题】使用 JUnit 5 的 spring-boot-starter-test【英文标题】:spring-boot-starter-test with JUnit 5 【发布时间】: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 刚刚试了一下,确实有效。谢谢! 【参考方案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.1
、Spring Boot 2.1.7.RELEASE
和JUnit 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 提到的排除路由是这里的方法。 正确,如果您根本不想包含它,则需要排除它。以上是关于使用 JUnit 5 的 spring-boot-starter-test的主要内容,如果未能解决你的问题,请参考以下文章
如何使用junit在spring-boot中测试常见错误ErrorController
如何 JUnit 测试 Spring-Boot 的 Application.java