java如何单元测试
单元测试基础概念
单元测试是针对程序中最小的可测试单元(如方法、类)的验证过程。在Java中,通常使用JUnit框架实现单元测试,结合Mockito等工具模拟依赖对象。
依赖配置
对于Maven项目,在pom.xml中添加JUnit和Mockito依赖:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.5.1</version>
<scope>test</scope>
</dependency>
测试类结构
测试类需与被测类同名且后缀为Test,例如CalculatorTest。使用JUnit 5的注解:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CalculatorTest {
@Test
void testAdd() {
Calculator calc = new Calculator();
assertEquals(5, calc.add(2, 3));
}
}
常用断言方法
assertEquals(expected, actual):验证预期值与实际值相等。assertTrue(condition):验证条件为真。assertThrows(Exception.class, () -> { ... }):验证代码块抛出指定异常。
Mock对象模拟依赖
使用Mockito模拟外部依赖的行为:
import static org.mockito.Mockito.*;
@Test
void testUserService() {
UserRepository mockRepo = mock(UserRepository.class);
when(mockRepo.findById(1)).thenReturn(new User(1, "Alice"));
UserService service = new UserService(mockRepo);
User user = service.getUser(1);
assertEquals("Alice", user.getName());
}
测试生命周期注解
@BeforeEach:每个测试方法前执行,用于初始化。@AfterEach:每个测试方法后执行,用于清理资源。@BeforeAll/@AfterAll:所有测试前后执行(静态方法)。
参数化测试
通过@ParameterizedTest实现多组输入测试:
@ParameterizedTest
@ValueSource(ints = {1, 2, 3})
void testIsPositive(int number) {
assertTrue(number > 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>
</executions>
</plugin>
最佳实践
- 测试名称应清晰描述行为,如
shouldReturnNullWhenInputIsInvalid。 - 避免测试依赖外部环境(如数据库、网络)。
- 每个测试仅验证一个逻辑点。
- 定期运行测试并修复失败用例。







