java如何做单元测试
单元测试的基本概念
单元测试是针对代码中最小可测试单元(如方法、类)的验证过程,通常使用框架如JUnit或TestNG。其核心目标是隔离代码块并验证其逻辑正确性。
使用JUnit框架
JUnit是Java最流行的单元测试框架,需添加依赖(以Maven为例):
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
测试类示例:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CalculatorTest {
@Test
public void testAdd() {
Calculator calc = new Calculator();
assertEquals(5, calc.add(2, 3));
}
}
常用断言方法
assertEquals(expected, actual):验证期望值与实际值相等。assertTrue(condition):验证条件为真。assertNull(object):验证对象为null。assertThrows(exceptionType, executable):验证是否抛出指定异常。
测试生命周期注解
@BeforeEach:每个测试方法前执行,用于初始化。@AfterEach:每个测试方法后执行,用于清理。@BeforeAll/@AfterAll:整个测试类的前后执行(静态方法)。
Mock对象的使用
当测试依赖外部服务(如数据库)时,使用Mockito模拟依赖:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.5.1</version>
<scope>test</scope>
</dependency>
示例:
import static org.mockito.Mockito.*;
@Test
public void testUserService() {
UserRepository mockRepo = mock(UserRepository.class);
when(mockRepo.findById(1L)).thenReturn(new User(1L, "Alice"));
UserService service = new UserService(mockRepo);
assertEquals("Alice", service.getUserName(1L));
}
参数化测试
通过@ParameterizedTest实现多组数据测试:
@ParameterizedTest
@ValueSource(ints = {1, 3, 5})
public void testIsOdd(int number) {
assertTrue(number % 2 != 0);
}
测试覆盖率工具
使用JaCoCo生成覆盖率报告(Maven配置):
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
运行mvn test后,报告位于target/site/jacoco/目录。
最佳实践
- 测试名称应描述预期行为(如
shouldReturnTrueWhenInputIsEven)。 - 避免测试依赖外部环境(如网络、数据库)。
- 每个测试仅验证一个逻辑点。
- 定期运行测试并修复失败用例。






