文档站点
Skip to content

测试入门 ​

Laravel 用 PHPUnit + php artisan test;Spring Boot 用 JUnit 5 + mvn test,测试代码放 src/test/java/,与主代码包结构一一对应。这篇先建立「Java 测试怎么组织」的整体认知。

测试结构 ​

src/
├── main/java/com/example/blog/...
└── test/java/com/example/blog/
    ├── post/PostServiceTest.java     ← 单元测试
    └── post/PostControllerTest.java  ← 集成测试

测试类命名规范:被测类名 + Test。运行方式:

bash
./mvnw test          # 跑全部测试
./mvnw test -Dtest=PostServiceTest   # 只跑某个测试类

TIP

对应 Laravel:

LaravelSpring Boot
phpunit.xmlpom.xml 的 test 依赖
tests/Feature、tests/Unitsrc/test/java 按包分
php artisan test./mvnw test
@test 方法@Test 注解方法

第一个单元测试 ​

java
package com.example.blog.post;

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

class PostServiceTest {

    @Test
    void 计算标题字数() {                       // 方法名可以用中文(可读性更好)
        String title = "Spring Boot 入门";
        assertEquals(16, title.length());
    }

    @Test
    void 空标题应该失败() {
        String title = "";
        assertTrue(title.isBlank());
    }
}

TIP

JUnit 5 用 @Test 标注测试方法,断言方法在 org.junit.jupiter.api.Assertions:

  • assertEquals(expected, actual)
  • assertTrue / assertFalse
  • assertNotNull / assertNull
  • assertThrows(RuntimeException.class, () -> ...)(断言抛异常,对应 Laravel 的 expectException)

单元测试 vs 集成测试 ​

类型测什么用不用数据库Spring 上下文
单元测试单个类/方法逻辑不用(Mock 掉依赖)不启动(快)
集成测试多层协作、完整请求用(H2/Testcontainers)启动完整上下文(慢)
java
// 单元测试:只测 Service 逻辑,把 Repository mock 掉
// 集成测试:@SpringBootTest + MockMvc,真实打接口

TIP

./mvnw test 默认两种都跑。单元测试要快(毫秒级),集成测试要少而精(跑一次秒级)。Laravel 的 Unit / Feature 区别同理。

测试专用配置 ​

测试用独立配置,别污染开发库。src/test/resources/application-test.yml:

yaml
spring:
  datasource:
    url: jdbc:h2:mem:testdb;MODE=MySQL
  jpa:
    hibernate:
      ddl-auto: create-drop      # 测试库自动建表
  sql:
    init:
      mode: never

测试类上指定 Profile:

java
@SpringBootTest
@ActiveProfiles("test")
class PostServiceIntegrationTest { ... }

TIP

测试数据库原则:用内存库(H2)或 Testcontainers 起真实库,绝不用开发/生产库。对应 Laravel 的 phpunit.xml 里配 DB_DATABASE=:memory:。

测试生命周期注解 ​

注解作用
@BeforeEach每个测试前执行(≈ setUp())
@AfterEach每个测试后执行
@BeforeAll测试类所有用例前执行一次
@AfterAll全部结束后执行一次
java
class PostServiceTest {

    @BeforeEach
    void setUp() {
        // 每个测试前重置状态
    }
}

测试金字塔(和 Laravel 一样的道理) ​

        ╱ 少数集成测试(跑通链路)
       ╱  多些 Service 测试(核心业务逻辑)
      ╱   大量单元测试(快、稳、覆盖边界)
  1. 业务逻辑放 Service 层 + 重点测 Service(Java 尤其如此:Controller 薄,逻辑都在 Service)
  2. Controller 用 MockMvc 做轻量集成测试
  3. 别为了覆盖率测 getter/setter

为什么 Service 测试是重点?

Java 的 @Transactional、@Cacheable 等关键逻辑都在 Service 层,且 Service 是依赖注入的中心。Service 测试 ≈ Laravel 的「控制器逻辑 + Model 逻辑」测试,覆盖它性价比最高。

实战建议 ​

  1. 测试方法名用中文描述行为(void 未登录访问返回401()),比 testLogin1 可读
  2. 一个测试只断言一件事
  3. 集成测试用 H2/Testcontainers,测试完数据自动清理
  4. 关键业务(支付、订单、权限)必须测,简单 CRUD 可以少测

下一节:HTTP 测试(MockMvc 打接口)和 模拟对象(Mockito)(mock 依赖)。

面向 PHP / Laravel 开发者的 Spring Boot 中文文档