Springboot Tdd

affaan-m/ECC/docs/zh-CN/skills/springboot-tdd

作者 affaan-mef648e01899ba3e8dc6371642deaaf64b4477775無授權條款275K 個星標收錄於 2026年10月9日更新於 2026年10月9日儲存庫4 天前更新

使用JUnit 5、Mockito、MockMvc、Testcontainers和JaCoCo进行Spring Boot的测试驱动开发。适用于添加功能、修复错误或重构时。

AI 產生的概覽

指導 Spring Boot 服務的測試驅動開發,使用 JUnit 5、Mockito、MockMvc、Testcontainers 與 JaCoCo。

功能
此技能為 Spring Boot 服務提供 TDD 工作流程指南,涵蓋先寫測試、實作、重構的循環,並以 80% 以上覆蓋率為目標。它提供單元測試(JUnit 5 與 Mockito)、Web 層測試(MockMvc)、整合測試(SpringBootTest)以及持久層測試(DataJpaTest 與 Testcontainers)的程式碼模式。此外還包含 JaCoCo 的 Maven 設定、斷言建議、測試資料建構器範例,以及 Maven 與 Gradle 的 CI 指令。
適用情境
適用於為 Spring Boot 服務新增功能或端點、修正錯誤、重構,或加入資料存取邏輯與安全規則的情境。也適合希望採用結構化測試先行方法並強制覆蓋率的團隊。
執行需求
僅為說明文件,不附帶指令碼。依指南操作需要具備 JUnit 5、Mockito、MockMvc、Testcontainers 與 JaCoCo 的 Spring Boot 專案,以及 Maven 或 Gradle,並為 Testcontainers 提供容器執行環境。

Spring Boot TDD 工作流程

适用于 Spring Boot 服务、覆盖率 80%+(单元 + 集成)的 TDD 指南。

何时使用

  • 新功能或端点
  • 错误修复或重构
  • 添加数据访问逻辑或安全规则

工作流程

  1. 先写测试(它们应该失败)
  2. 实现最小代码以通过测试
  3. 在测试通过后进行重构
  4. 强制覆盖率(JaCoCo)

单元测试 (JUnit 5 + Mockito)

java
@ExtendWith(MockitoExtension.class)class MarketServiceTest {  @Mock MarketRepository repo;  @InjectMocks MarketService service;
  @Test  void createsMarket() {    CreateMarketRequest req = new CreateMarketRequest("name", "desc", Instant.now(), List.of("cat"));    when(repo.save(any())).thenAnswer(inv -> inv.getArgument(0));
    Market result = service.create(req);
    assertThat(result.name()).isEqualTo("name");    verify(repo).save(any());  }}

模式:

  • Arrange-Act-Assert
  • 避免部分模拟;优先使用显式桩
  • 使用 @ParameterizedTest 处理变体

Web 层测试 (MockMvc)

java
@WebMvcTest(MarketController.class)class MarketControllerTest {  @Autowired MockMvc mockMvc;  @MockBean MarketService marketService;
  @Test  void returnsMarkets() throws Exception {    when(marketService.list(any())).thenReturn(Page.empty());
    mockMvc.perform(get("/api/markets"))        .andExpect(status().isOk())        .andExpect(jsonPath("$.content").isArray());  }}

集成测试 (SpringBootTest)

java
@SpringBootTest@AutoConfigureMockMvc@ActiveProfiles("test")class MarketIntegrationTest {  @Autowired MockMvc mockMvc;
  @Test  void createsMarket() throws Exception {    mockMvc.perform(post("/api/markets")        .contentType(MediaType.APPLICATION_JSON)        .content("""          {"name":"Test","description":"Desc","endDate":"2030-01-01T00:00:00Z","categories":["general"]}        """))      .andExpect(status().isCreated());  }}

持久层测试 (DataJpaTest)

java
@DataJpaTest@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)@Import(TestContainersConfig.class)class MarketRepositoryTest {  @Autowired MarketRepository repo;
  @Test  void savesAndFinds() {    MarketEntity entity = new MarketEntity();    entity.setName("Test");    repo.save(entity);
    Optional<MarketEntity> found = repo.findByName("Test");    assertThat(found).isPresent();  }}

Testcontainers

  • 对 Postgres/Redis 使用可复用的容器以镜像生产环境
  • 通过 @DynamicPropertySource 连接,将 JDBC URL 注入 Spring 上下文

覆盖率 (JaCoCo)

Maven 片段:

xml
<plugin>  <groupId>org.jacoco</groupId>  <artifactId>jacoco-maven-plugin</artifactId>  <version>0.8.14</version>  <executions>    <execution>      <goals><goal>prepare-agent</goal></goals>    </execution>    <execution>      <id>report</id>      <phase>verify</phase>      <goals><goal>report</goal></goals>    </execution>  </executions></plugin>

断言

  • 为可读性,优先使用 AssertJ (assertThat)
  • 对于 JSON 响应,使用 jsonPath
  • 对于异常:assertThatThrownBy(...)

测试数据构建器

java
class MarketBuilder {  private String name = "Test";  MarketBuilder withName(String name) { this.name = name; return this; }  Market build() { return new Market(null, name, MarketStatus.ACTIVE); }}

CI 命令

  • Maven: mvn -T 4 test 或 mvn verify
  • Gradle: ./gradlew test jacocoTestReport

记住:保持测试快速、隔离且确定。测试行为,而非实现细节。

來源與署名

來源:affaan-m/ECC位於docs/zh-CN/skills/springboot-tdd提交ef648e0

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架