[TOC]
# 一. 单元测试简单流程
## 1.1 准备待测试代码
Java程序最小的功能单元是方法,因此,对Java程序进行单元测试就是针对单个Java方法的测试。对于高质量的代码来说,测试覆盖率应该在80%以上。
- HelloJava.java
```
package com;
public class HelloJava {
public int age;
public HelloJava(int age) {
this.age = age;
}
}
```
## 1.2 准备单元测试
### 1.2.1 引入JUnit5依赖
```
org.junit.jupiter
junit-jupiter-api
5.7.0
test
```
### 1.2.2 编写单元测试
- 常见注意事项
- 测试类的包名应该和待测试的包名对应。
- 测试类和待测试类名称一一对应:`HelloJava` 对应 `HelloJavaTest`
- 添加 `@Test` 注解
- 一个方法对应一个测试方法
```
package com;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
public class HelloJavaTest {
@Test
public void testHelloJava() {
HelloJava p = new HelloJava(9);
assertEquals(9, p.age);
}
}
```
## 1.3 运行单元测试
- 使用 mvn 命令运行测试
```
// 只运行单元测试
mvn test
// 打包时自动测试
mvn clean package
```
# 二. JUnit5提供常用内容
## 2.1 常用注解
| Annotations | 描述 |
|--------------|------------------------------|
| @BeforeEach | 在方法上注解,在每个测试方法运行之前执行。
| @AfterEach | 在方法上注解,在每个测试方法运行之后执行
| @BeforeAll | 该注解方法会在所有测试方法之前运行,该方法必须是静态的。
| @AfterAll | 该注解方法会在所有测试方法之后运行,该方法必须是静态的。
| @Test | 用于将方法标记为测试方法
| @DisplayName | 用于为测试类或测试方法提供任何自定义显示名称
| @Disable | 用于禁用或忽略测试类或方法
## 2.2 常用assert
- assertEquals(): 期待相等
- assertNotEquals(): 期待不相等
- assertTrue(): 期待结果为true
- assertFalse(): 期待结果为false
- assertNull(): 期待结果为非null
- assertNotNull(): 期待结果为非null
- assertDoesThrow(): 期待抛出错误
- assertDoesNotThrow(): 期待不抛出错误
- assertSame(): 期待同一个对象
- assertNotSame(): 期待不是同一个对象
- assertTimeout(): 期待超时
- assertArrayEquals(): 期待结果为数组并与期望数组每个元素的值均相等
# 三. JUnit4和JUnit5对比
| JUnit5 | JUnit4 |
|--------------|--------------|
| @Test | @Test |
| @DisplayName | N/A |
| @BeforeEach | @Before |
| @AfterEach | @After |
| @BeforeAll | @BeforeClass |
| @AfterAll | @AfterClass |
| @Disable | @Ignore |
| | |
# 四. JUnit5最佳实践
- 初始化数据库清理数据库可以使用 @BeforeAll 和 @AfterAll 注解,它们只能初始化静态变量。
```
public class DatabaseTest {
static Database db;
@BeforeAll
public static void initDatabase() {
db = createDb(...);
}
@AfterAll
public static void dropDatabase() {
...
}
}
```
- 对于实例变量,在@BeforeEach中初始化,在@AfterEach中清理,它们在各个@Test方法中互不影响,因为是不同的实例;
- 对于静态变量,在@BeforeAll中初始化,在@AfterAll中清理,它们在各个@Test方法中均是唯一实例,会影响各个@Test方法。
- 每次运行一个@Test方法前,JUnit首先创建一个XxxTest实例,因此,每个@Test方法内部的成员变量都是独立的,不能也无法把成员变量的状态从一个@Test方法带到另一个@Test方法。
- 参考资料
https://www.liaoxuefeng.com/wiki/1252599548343744/1255945269146912
https://tonydeng.github.io/2017/10/10/junit-5-annotations/