# JUnit5
Spring Boot 2.2.0 开始引入 JUnit5 作为默认单元测试库。
# 参考文档
# 组成
Junit5 由三部分组成:
- JUnit Platform
- JUnit Jupiter
- JUnit Vintage
# JUnit Platform
JUnit Platform 是在 JVM 上启动测试框架的基础,不仅支持 JUnit 自制的测试引擎,其他测试引擎也都可以接入。
# Junit Jupiter
JUnit Jupiter 提供了 JUnit5 新的编程模型,是 JUnit5 新特性的核心。内部包含了一个测试引擎,用于在 JUnit Platform 上运行。
# Junit Vintage
由于 JUnit 项目已经开发了很多年,为了照顾老的项目,JUnit Vintage 提供了兼容 JUnit4.x、JUnit3.x 的测试引擎。
Spring Boot 2.4 之后移除了默认对 Vintage 的依赖。如果需要使用 JUnit4 则需要自行引入依赖:
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
2
3
4
5
6
7
8
9
10
11
# 注解 Annotations
@Test
:表示方法是测试方法,但是与 Junit4 的@Test
不同,它的职责非常单一,不能声明任何属性,拓展的测试将会由 Jupiter 提供额外测试。@DisplayName
:为测试类或测试方法设置展示名称。@ParameterizedTest
:表示方法是参数化测试。@RepeatedTest
:表示方法可重复执行。@BeforeEach
:表示在每个单元测试之前执行。@AfterEach
:表示在每个单元测试之后执行。@BeforeAll
:表示在所有单元测试之前执行。- 要加 static 关键字修饰,因为只会在整个测试类之前运行一次。
@AfterAll
:表示在所有单元测试之后执行。- 要加 static 修饰,理由同上。
@Disabled
:表示测试类或测试方法不执行。- 一个测试类中多个测试实例,该注解可以选择禁用某个实例。
@TimeOut
:表示测试方法运行如果超过了指定时间,将会返回错误。@ExtendWith
:为测试类或测试方法提供扩展类引用。- 之前版本使用
@RunWith
- 之前版本使用
@Tag
:表示单元测试类别,类似于 JUnit4 中的@Categories
。
# Assertions 断言
示例:Assertions.assertEquals(expected, actual, message)
一个 test 中有两处断言,前面的断言失败后,程序不会继续执行。
# 简单断言
- assertEquals,判断两个对象或原始类型是否相等
- assertNotEquals
- assertSame,判断两个对象的引用是否指向同一个对象
- assertNotSame
- assertNull,判断给定的对象引用是否为 Null
- assertNotNull
- assertTrue,判断给定的值是否为 true
- assertFalse
# 数组断言
- assertArrayEquals,判断两个对象或原始类型的数组是否相等。
这里判断的是数组的内容,而不是数组的地址。
# 组合断言
判定多个断言是否都成功。
示例:
assertAll("test",
() -> assertTrue(1 == 1, "返回的不是 true"),
() -> assertEquals(2, 1, "得到的值不是 2"));
2
3
这里只有两个断言都成功的时候,才会成功,有一个断言不成功,那么 assertAll 就执行失败。
# 异常断言
示例:
assertThrows(
NullPointerException.class,
() -> { int q = 9 / 0; },
"竟然正常运行了"
);
2
3
4
5
期望的逻辑执行时会发生 NPE,但是却没有发生这个异常就,那么就显示自定义的 Message。
# 超时断言
示例:
assertTimeout(Duration.ofMillis(1), () -> {
Thread.sleep(2);
}, "程序超时了");
2
3
期望程序在 1 毫秒执行完毕,但是这里却大于 1 毫秒,所有这里断言失败了,打印信息 "程序超时了"。
# 快速失败
fail("测试失败");
# Assumptions 假设
也可以理解为前置条件。
Assumptions.assumeTrue("56".equals("ss"),"假设不成立,程序不继续执行");
假设成立,代码会向下执行,不成立的时候,程序会终止,直接跳过 test。
断言不满足会报失败,而假设则是不继续执行。
# 嵌套测试
在嵌套测试时内层的测试会触发外层的 BeforeEach ... 方法,但是外层的方法不会驱动内层的方法。
# Parameterized Tests 参数化测试
生成参数注解:
@ValueSource
@NullSource
@EnumSource
@CsvFileSource
@MethodSource
- 这种方式需要导入的方法需要是 static 的,并且返回值是 Stream 的。
示例:
@DisplayName("Parameterized Tests")
@ParameterizedTest
@ValueSource(ints = {1,2,3})
void ParameterizedTest(int i) {
System.out.println(i);
}
2
3
4
5
6
# 讨论区
由于评论过多会影响页面最下方的导航,故将评论区做默认折叠处理。
点击查看评论区内容,渴望您的宝贵建议~
← Test