JUnit 4与JUnit 5的差异详解

概述

在进行SpringBoot项目单元测试时,发现有时候给类打上
@SpringBootTest注解就能运行项目,但有时候需要@RunWith(SpringRunner.class)@SpringBootTest注解才能运行,你有研究过这是为什么吗?本文就来讲一下这个问题。


Spring Boot中JUnit 4JUnit 5的差异详解

一、核心差异概述

特性 JUnit 4 JUnit 5
架构 单一JAR包 模块化设计(Jupiter, Vintage, Platform)
包结构 org.junit org.junit.jupiter.api
Spring Boot 2.x 默认集成 需手动配置
Spring Boot 3.x+ 需降级依赖 默认集成

二、依赖配置对比

1. Maven依赖

xml 复制代码
<!-- JUnit 4 典型依赖 -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
</dependency>

<!-- JUnit 5 典型依赖 -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <scope>test</scope>
</dependency>

三、注解差异详解

1. 基础注解对照表

功能 JUnit 4 注解 JUnit 5 注解
测试方法 @Test @Test
前置初始化 @Before @BeforeEach
后置清理 @After @AfterEach
类级别初始化 @BeforeClass @BeforeAll
类级别清理 @AfterClass @AfterAll
禁用测试 @Ignore @Disabled

2. Spring集成测试

java 复制代码
// JUnit 4 写法
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {
    // ...
}

// JUnit 5 写法(无需@RunWith)
@SpringBootTest
@ExtendWith(SpringExtension.class) // 可选(Spring Boot 2.1+自动配置)
public class UserServiceTest {
    // ...
}

四、断言与假设

1. 断言API对比

java 复制代码
// JUnit 4
import org.junit.Assert;
Assert.assertEquals(expected, actual);

// JUnit 5(支持Lambda表达式)
import org.junit.jupiter.api.Assertions;
Assertions.assertEquals(expected, actual, 
    () -> "自定义错误信息");

2. 链式断言(JUnit 5新增)

java 复制代码
assertAll("用户信息校验",
    () -> assertEquals("John", user.firstName()),
    () -> assertEquals("Doe", user.lastName())
);

五、兼容性与迁移方案

1. 混合测试支持

xml 复制代码
<!-- 在JUnit 5环境中运行JUnit 4测试 -->
<dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <scope>test</scope>
</dependency>

junit-vintage-engine是JUnit 5提供的一个兼容引擎,允许在JUnit 5环境中运行JUnit 3和JUnit 4的测试。这是为了帮助开发者在迁移到JUnit 5时,能够继续运行现有的JUnit 4(甚至JUnit 3)测试用例,而不需要立即重写所有测试代码。

作用和功能
  1. 兼容性支持:

    • junit-vintage-engine提供了一个运行时引擎,使得JUnit 4和JUnit 3的测试可以在JUnit 5的测试平台上运行。这对于拥有大量现有测试的项目特别有用,因为它允许逐步迁移到JUnit 5。
  2. 无缝集成:

    • 通过添加这个依赖,JUnit 5的测试运行器(如IDE内置的运行器或构建工具中的运行器)可以识别并执行使用旧版JUnit API编写的测试。
  3. 迁移过渡:

    • 在项目中同时使用JUnit 4和JUnit 5测试时,junit-vintage-engine可以作为一个过渡工具。你可以逐步将新的测试用例用JUnit 5编写,而旧的测试用例继续使用JUnit 4,直到有时间和资源进行全面迁移。
使用场景
  • 渐进式迁移 : 如果你的项目中已经有大量的JUnit 4测试,并且不可能一次性迁移到JUnit 5,junit-vintage-engine提供了一种渐进式迁移路径。
  • 遗留系统维护: 在维护遗留系统时,可能需要继续支持旧的JUnit测试框架,而新功能使用JUnit 5进行测试。
如何使用

在你的项目的构建文件中(如Maven的pom.xml),添加以下依赖:

xml 复制代码
<dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <scope>test</scope>
</dependency>
注意事项
  • 兼容性问题: 在某些情况下,JUnit 4和JUnit 5的注解和特性可能会冲突,因此在迁移过程中需要注意这些潜在问题。
  • 性能影响 : 虽然junit-vintage-engine提供了兼容性支持,但在某些情况下可能会引入额外的运行时开销。

通过使用junit-vintage-engine,开发者可以在不立即重写现有测试的情况下,享受JUnit 5的现代特性和改进的运行环境。这是一个非常有用的工具,特别是在大型项目的测试框架升级过程中。

2. 常见迁移问题

  • ❌ 错误:java.lang.NoClassDefFoundError: org/junit/runner/manipulation/Filter
  • ✅ 解决:检查是否同时存在junit4junit-jupiter依赖冲突

六、最佳实践建议

  1. 新项目 :Spring Boot 3.x+默认使用JUnit 5,无需额外配置
  2. 旧项目迁移
    • 逐步替换@Before/@After@BeforeEach/@AfterEach
    • 使用junit-vintage-engine保持向下兼容
  3. 特性升级 :利用JUnit 5@ParameterizedTest实现参数化测试

七、总结

JUnit 5在Spring Boot中的使用更加现代化,推荐新项目直接采用。对于历史项目,可通过渐进式迁移策略平稳过渡。关注Spring Boot版本与JUnit版本的对应关系,可有效避免兼容性问题。


附录 :Spring Boot版本与JUnit默认支持对照表

Spring Boot版本 默认JUnit版本
2.4.x及以下 JUnit 4
2.5.x+ JUnit 5
3.0.x+ JUnit 5

希望这篇对比分析能帮助您更好地在Spring Boot项目中运用单元测试!如果有具体使用场景的问题,欢迎在评论区交流讨论。

相关推荐
圈圈编码6 分钟前
Spring Task 定时任务
java·前端·spring
俏布斯19 分钟前
算法日常记录
java·算法·leetcode
276695829224 分钟前
美团民宿 mtgsig 小程序 mtgsig1.2 分析
java·python·小程序·美团·mtgsig·mtgsig1.2·美团民宿
爱的叹息25 分钟前
Java 连接 Redis 的驱动(Jedis、Lettuce、Redisson、Spring Data Redis)分类及对比
java·redis·spring
程序猿chen34 分钟前
《JVM考古现场(十五):熵火燎原——从量子递归到热寂晶壁的代码涅槃》
java·jvm·git·后端·java-ee·区块链·量子计算
松韬1 小时前
Spring + Redisson:从 0 到 1 搭建高可用分布式缓存系统
java·redis·分布式·spring·缓存
绝顶少年1 小时前
Spring Boot 注解:深度解析与应用场景
java·spring boot·后端
心灵宝贝1 小时前
Tomcat 部署 Jenkins.war 详细教程(含常见问题解决)
java·tomcat·jenkins
天上掉下来个程小白1 小时前
Redis-14.在Java中操作Redis-Spring Data Redis使用方式-操作列表类型的数据
java·redis·spring·springboot·苍穹外卖
ゞ 正在缓冲99%…2 小时前
leetcode22.括号生成
java·算法·leetcode·回溯