已复制
全屏展示
复制代码

Java单元测试JUnit5总结


· 3 min read

一. 单元测试简单流程

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方法。

🔗

文章推荐