Skip to content

2026-08-27 · 给方法写"自动验证器",改代码后跑一遍就知道有没有坏。

单元测试

1. 为什么要写单元测试

java
// 没有测试的情况
public int add(int a, int b) {
    return a + b;
}

// 你改成了
public int add(int a, int b) {
    return a - b; // 手滑写错了
}
// 没人发现,上线后出 bug

有测试的情况:

java
@Test
public void testAdd() {
    assertEquals(5, add(2, 3));  // 改完跑测试,立刻发现
}

单元测试 = 给方法写"自动验证器",改代码后跑一遍就知道有没有坏。

2. JUnit 基础

依赖

Spring Boot 项目自带 JUnit 5,不需要额外加依赖。如果需要手动加:

xml
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.10.0</version>
    <scope>test</scope>
</dependency>

第一个测试

java
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class CalculatorTest {

    @Test
    public void testAdd() {
        Calculator calc = new Calculator();
        assertEquals(5, calc.add(2, 3));
    }

    @Test
    public void testSubtract() {
        Calculator calc = new Calculator();
        assertEquals(1, calc.subtract(3, 2));
    }
}

运行测试

  • 右键测试类 → Run 'CalculatorTest'
  • 或点方法左边的绿色箭头
  • 绿色 = 通过,红色 = 失败(会显示期望值和实际值)

3. 常用断言方法

java
// 相等(最常用)
assertEquals(期望值, 实际值);
assertEquals("Hello", s.toUpperCase());

// true/false
assertTrue(result > 0);
assertFalse(list.isEmpty());

// null
assertNull(obj);
assertNotNull(obj);

// 异常(断言抛出了指定异常)
assertThrows(ArithmeticException.class, () -> {
    int result = 10 / 0;
});

最常用的是 assertEqualsassertTrueassertThrows,记住这三个够日常用了。

4. 测试初始化:@BeforeEach

多个测试方法需要共享同一个对象时,用 @BeforeEach 初始化,避免每个测试里都 new 一遍:

java
import org.junit.jupiter.api.*;

public class UserServiceTest {

    private UserService service;

    @BeforeEach
    void setUp() {
        // 每个测试方法执行前运行
        service = new UserService();
    }

    @Test
    void testSave() {
        service.save(new User("张三"));
        assertNotNull(service.findByName("张三"));
    }

    @Test
    void testDelete() {
        service.save(new User("李四"));
        service.delete("李四");
        assertNull(service.findByName("李四"));
    }
}

大多数测试只需要 @Test + 必要时 @BeforeEach@BeforeAll/@AfterAll(类级别一次性初始化和清理)偶尔用,遇到再查。

5. 测试目录结构

Maven 约定:测试代码放在 src/test/java/,和源代码一一对应:

src/
├── main/java/com/example/
│   ├── User.java
│   └── UserService.java
└── test/java/com/example/
    ├── UserTest.java
    └── UserServiceTest.java

测试类名通常是 原类名 + Test,放在同一个包下。

6. IDEA 运行测试

  • 右键测试类 → Run 'XxxTest':运行整个测试类
  • 右键测试方法 → Run 'testXxx()':只运行一个方法
  • 点类名左边的绿色箭头 → 运行所有测试
  • Run 面板:绿色进度条 = 全部通过,红色 = 有失败

7. 什么时候写测试

  • 必须写:核心业务逻辑(订单、支付、数据处理)
  • 建议写:工具类、复杂算法
  • 不用写:getter/setter(Lombok 生成的)、简单 CRUD(Spring Boot 会帮你测)

Spring Boot 项目里,Service 层和工具类是测试的重点。Controller 层用 MockMvc 测试,等学 Spring 再讲。