【SpringBoot】31 核心功能 - 单元测试 - JUnit5 单元测试中的断言机制——验证你的代码是否按预期执行了
文章目录
- 前言
 - 一、什么是断言?为什么它这么重要?
 - 二、简单断言:最常用的几个
 - 1. `assertEquals`
 - 2. `assertNotEquals`
 - 3. `assertSame` / `assertNotSame`
 - 4. `assertTrue` / `assertFalse`
 - 5. `assertNull` / `assertNotNull`
 
- 三、数组断言:对比数组是否一致
 - 四、组合断言:一次性验证多个条件
 - 五、异常断言:测试代码是否抛出预期异常
 - 六、超时断言:防止测试卡死
 - 七、快速失败:直接让测试失败
 - 八、实战案例:测试 Redis 连接
 - 九、总结:断言是测试的灵魂
 - 十、写在最后
 
前言
大家好,我是正在写单元测试的“小开发”一枚。最近在项目里用 JUnit5 做测试,发现了一个特别重要的东西——断言(Assertions)。一开始我也觉得“不就是判断一下结果对不对吗?”,但真正用起来才发现,它不只是“判断”,而是整个测试逻辑的“大脑”。
今天就来和大家聊聊我在实际开发中是如何一步步理解并使用 JUnit5 的断言机制 的。我会像平时写代码一样,一边讲思路,一边贴代码,顺便看看测试效果,保证你一看就懂!
一、什么是断言?为什么它这么重要?
先说点基础的。
断言(assertions),是单元测试的核心部分。它的作用是:验证你的代码是否按预期执行了。
比如你写了个加法函数 add(a, b),你期望 add(2, 3) 返回 5。那你就得用断言去检查这个返回值是不是真的等于 5。
如果等于 → 测试通过 ✅
 如果不等于 → 测试失败 ❌
这就是断言的作用。
在 JUnit5 中,所有断言都是静态方法,来自 org.junit.jupiter.api.Assertions 类。我们接下来一个个来看。
二、简单断言:最常用的几个
这是最基础的断言,用来做简单的值判断。
1. assertEquals
 
判断两个值是否相等。
@Test
@DisplayName("简单断言:相等")
public void testEquals() {int result = 2 + 3;assertEquals(5, result);
}
 
✅ 效果:如果 result 是 5,测试通过;否则报错。
2. assertNotEquals
 
判断两个值是否不相等。
@Test
@DisplayName("简单断言:不相等")
public void testNotEquals() {int result = 2 + 3;assertNotEquals(6, result);
}
 
✅ 如果结果不是 6,就通过;如果是 6 就失败。
3. assertSame / assertNotSame
 
判断两个引用是否指向同一个对象。
@Test
@DisplayName("引用相同")
public void testSame() {String str1 = "hello";String str2 = str1;assertSame(str1, str2); // 会通过,因为是同一个对象
}@Test
@DisplayName("引用不同")
public void testNotSame() {String str1 = "hello";String str2 = new String("hello");assertNotSame(str1, str2); // 会通过,虽然内容一样,但对象不同
}
 
⚠️ 注意:assertSame 看的是内存地址,不是内容!
4. assertTrue / assertFalse
 
判断布尔值。
@Test
@DisplayName("布尔断言")
public void testBoolean() {assertTrue(2 > 1);assertFalse(2 < 1);
}
 
5. assertNull / assertNotNull
 
判断对象是否为 null。
@Test
@DisplayName("null 断言")
public void testNull() {String str = null;assertNull(str);String notNull = "abc";assertNotNull(notNull);
}
 
三、数组断言:对比数组是否一致
有时候我们需要比较两个数组是否相等,这时候用 assertArrayEquals。
@Test
@DisplayName("数组断言")
public void array() {int[] arr1 = {1, 2};int[] arr2 = {1, 2};assertArrayEquals(arr1, arr2);
}
 
✅ 只要顺序和内容都一样,就会通过。
如果你改成 {2, 1},就会失败。
四、组合断言:一次性验证多个条件
有时候你想一次检查多个断言,可以用 assertAll。
@Test
@DisplayName("组合断言")
public void assertAll() {assertAll(() -> assertEquals(2, 1 + 1),() -> assertTrue(1 > 0),() -> assertNotNull("hello"));
}
 
💡 优点:即使其中一个失败,其他还会继续执行(不会中断),你可以看到所有问题。
👉 比如上面如果第一个断言失败了,后面两个也会跑完,方便调试。
五、异常断言:测试代码是否抛出预期异常
以前用 JUnit4 要测异常,得用 @Rule 或 ExpectedException,很麻烦。
现在 JUnit5 有 assertThrows,超简单!
@Test
@DisplayName("异常断言")
public void testException() {Throwable exception = assertThrows(ArithmeticException.class,() -> {int result = 10 / 0;});assertTrue(exception.getMessage().contains("/ by zero"));
}
 
✅ 这个测试会成功,因为我们确实抛出了 ArithmeticException。
如果没抛异常,或者抛了别的异常,就会失败。
六、超时断言:防止测试卡死
有些方法可能因为网络或 IO 操作太慢,导致测试一直挂住。
我们可以设置超时时间。
@Test
@DisplayName("超时断言")
public void timeoutTest() {Assertions.assertTimeout(Duration.ofMillis(1000), () -> {Thread.sleep(500); // 这个不会超时});
}
 
✅ 如果方法执行超过 1 秒,就会抛异常。
你可以试试把 sleep(500) 改成 sleep(1500),然后看测试失败。
七、快速失败:直接让测试失败
有时候你想手动让测试失败,比如某个条件不满足时强制失败。
用 fail() 方法:
@Test
@DisplayName("快速失败")
public void shouldFail() {fail("This should fail");
}
 
✅ 这个测试一定会失败,并输出提示信息。
这在写测试框架或模拟某些边界情况时很有用。
八、实战案例:测试 Redis 连接
我之前遇到一个问题,测试 Redis 连接的时候,连接失败了,但测试没报错,只打印了日志。
比如这样:
@Test
@DisplayName("测试 Redis")
public void testRedis() {try {redisTemplate.opsForValue().get("test");} catch (Exception e) {System.err.println("Redis 连接失败:" + e.getMessage());}
}
 
但这只是打印,测试依然通过了!
这不是我们想要的。
所以我们应该用断言来捕获异常:
@Test
@DisplayName("测试 Redis 连接异常")
public void testRedisConnection() {assertThrows(RedisConnectionFailureException.class,() -> redisTemplate.opsForValue().get("test"));
}
 
或者更通用一点:
@Test
@DisplayName("Redis 连接应失败")
public void testRedisFail() {Throwable exception = assertThrows(Exception.class, () -> {redisTemplate.opsForValue().get("test");});assertTrue(exception.getMessage().contains("connection"));
}
 
这样,一旦连接失败,测试就会明确失败,而不是默默忽略。
九、总结:断言是测试的灵魂
| 断言类型 | 用途 | 
|---|---|
assertEquals, assertNotEquals | 检查值是否相等 | 
assertSame, assertNotSame | 检查引用是否相同 | 
assertTrue, assertFalse | 检查布尔条件 | 
assertNull, assertNotNull | 检查 null | 
assertArrayEquals | 检查数组是否相等 | 
assertAll | 组合多个断言 | 
assertThrows | 检查是否抛出特定异常 | 
assertTimeout | 设置超时时间 | 
fail() | 手动让测试失败 | 
这些断言方法就像“裁判”,帮你判断代码行为是否符合预期。
十、写在最后
刚开始写测试时,我也只是简单地用 assertEquals,后来才慢慢发现,好的断言能让测试更清晰、更健壮。
比如:
- 用 
assertThrows而不是 try-catch - 用 
assertAll避免中途失败中断 - 用 
assertTimeout防止测试卡住 
这些都是“细节控”的体现,但正是这些细节,决定了你的测试是否可靠。
所以,别小看断言,它是你代码质量的“守护神”。
📌 附:完整测试类示例
import org.junit.jupiter.api.*;
import java.time.Duration;class MyTests {@Test@DisplayName("简单断言")public void simpleAssert() {assertEquals(5, 2 + 3);assertTrue(1 > 0);assertNotNull("hello");}@Test@DisplayName("异常断言")public void exceptionAssert() {assertThrows(ArithmeticException.class, () -> {int x = 10 / 0;});}@Test@DisplayName("超时断言")public void timeoutAssert() {Assertions.assertTimeout(Duration.ofMillis(1000), () -> {Thread.sleep(500);});}@Test@DisplayName("组合断言")public void allAssert() {assertAll(() -> assertEquals(2, 1 + 1),() -> assertTrue(true),() -> assertNotNull("test"));}
}
 
好了,今天的分享就到这里。希望这篇“边学边写”的博客对你有帮助。如果你也在写测试,欢迎留言交流你的断言技巧!
