Java单元测试JUnit5总结
一. 单元测试简单流程
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 准备单元测试
引入JUnit5依赖
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
编写单元测试
- 常见注意事项
- 测试类的包名应该和待测试的包名对应。
- 测试类和待测试类名称一一对应:
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方法。