spring-boot-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Spring Boot Testing

Spring Boot 测试

Expert guide for testing Spring Boot 4 applications with modern patterns and best practices.
采用现代模式与最佳实践的Spring Boot 4应用测试专家指南。

Core Principles

核心原则

  1. Test Pyramid: Unit (fast) > Slice (focused) > Integration (complete)
  2. Right Tool: Use the narrowest slice that gives you confidence
  3. AssertJ Style: Fluent, readable assertions over verbose matchers
  4. Modern APIs: Prefer MockMvcTester and RestTestClient over legacy alternatives
  1. 测试金字塔:单元测试(快速)> 切片测试(聚焦)> 集成测试(完整)
  2. 合适工具:使用能为你提供信心的最窄范围测试切片
  3. AssertJ风格:使用流畅、易读的断言替代冗长的匹配器
  4. 现代API:优先使用MockMvcTester和RestTestClient而非旧版替代方案

Which Test Slice?

选择哪种测试切片?

ScenarioAnnotationReference
Controller + HTTP semantics
@WebMvcTest
references/webmvctest.md
Repository + JPA queries
@DataJpaTest
references/datajpatest.md
REST client + external APIs
@RestClientTest
references/restclienttest.md
JSON (de)serialization
@JsonTest
See references/test-slices-overview.md
Full application
@SpringBootTest
See references/test-slices-overview.md
场景注解参考文档
控制器 + HTTP语义
@WebMvcTest
references/webmvctest.md
仓库 + JPA查询
@DataJpaTest
references/datajpatest.md
REST客户端 + 外部API
@RestClientTest
references/restclienttest.md
JSON(反)序列化
@JsonTest
参见 references/test-slices-overview.md
完整应用
@SpringBootTest
参见 references/test-slices-overview.md

Test Slices Reference

测试切片参考文档

  • references/test-slices-overview.md - Decision matrix and comparison
  • references/webmvctest.md - Web layer with MockMvc
  • references/datajpatest.md - Data layer with Testcontainers
  • references/restclienttest.md - REST client testing
  • references/test-slices-overview.md - 决策矩阵与对比
  • references/webmvctest.md - 结合MockMvc的Web层测试
  • references/datajpatest.md - 结合Testcontainers的数据层测试
  • references/restclienttest.md - REST客户端测试

Testing Tools Reference

测试工具参考文档

  • references/mockmvc-tester.md - AssertJ-style MockMvc (recommended)
  • references/mockmvc-classic.md - Traditional MockMvc
  • references/resttestclient.md - Spring Boot 4+ REST client
  • references/mockitobean.md - Mocking dependencies
  • references/mockmvc-tester.md - 采用AssertJ风格的MockMvc(推荐)
  • references/mockmvc-classic.md - 传统MockMvc
  • references/resttestclient.md - Spring Boot 4+ REST客户端
  • references/mockitobean.md - 依赖模拟

Assertion Libraries

断言库

  • references/assertj-basics.md - Core AssertJ patterns
  • references/assertj-collections.md - Collection assertions
  • references/assertj-basics.md - 核心AssertJ模式
  • references/assertj-collections.md - 集合断言

Testcontainers

Testcontainers

  • references/testcontainers-jdbc.md - PostgreSQL, MySQL, etc.
  • references/testcontainers-jdbc.md - PostgreSQL、MySQL等数据库测试

Test Data Generation

测试数据生成

  • references/instancio.md - Generate complex test objects (3+ properties)
  • references/instancio.md - 生成复杂测试对象(3个以上属性)

Performance & Migration

性能与迁移

  • references/context-caching.md - Speed up test suites
  • references/sb4-migration.md - Spring Boot 4.0 changes
  • references/context-caching.md - 加速测试套件
  • references/sb4-migration.md - Spring Boot 4.0变更

Quick Decision Tree

快速决策树

Testing a controller endpoint?
  Yes → @WebMvcTest with MockMvcTester

Testing repository queries?
  Yes → @DataJpaTest with Testcontainers (real DB)

Testing business logic in service?
  Yes → Plain JUnit + Mockito (no Spring context)

Testing external API client?
  Yes → @RestClientTest with MockRestServiceServer

Testing JSON mapping?
  Yes → @JsonTest

Need full integration test?
  Yes → @SpringBootTest with minimal context config
Testing a controller endpoint?
  Yes → @WebMvcTest with MockMvcTester

Testing repository queries?
  Yes → @DataJpaTest with Testcontainers (real DB)

Testing business logic in service?
  Yes → Plain JUnit + Mockito (no Spring context)

Testing external API client?
  Yes → @RestClientTest with MockRestServiceServer

Testing JSON mapping?
  Yes → @JsonTest

Need full integration test?
  Yes → @SpringBootTest with minimal context config

Spring Boot 4 Highlights

Spring Boot 4 亮点

  • RestTestClient: Modern alternative to TestRestTemplate
  • @MockitoBean: Replaces @MockBean (deprecated)
  • MockMvcTester: AssertJ-style assertions for web tests
  • Modular starters: Technology-specific test starters
  • Context pausing: Automatic pausing of cached contexts (Spring Framework 7)
  • RestTestClient: TestRestTemplate的现代替代方案
  • @MockitoBean: 替代已弃用的@MockBean
  • MockMvcTester: 用于Web测试的AssertJ风格断言
  • 模块化启动器: 特定技术的测试启动器
  • 上下文暂停: 缓存上下文自动暂停(Spring Framework 7)

Testing Best Practices

测试最佳实践

Code Complexity Assessment

代码复杂度评估

When a method or class is too complex to test effectively:
  1. Analyze complexity - If you need more than 5-7 test cases to cover a single method, it's likely too complex
  2. Recommend refactoring - Suggest breaking the code into smaller, focused functions
  3. User decision - If the user agrees to refactor, help identify extraction points
  4. Proceed if needed - If the user decides to continue with the complex code, implement tests despite the difficulty
Example of refactoring recommendation:
java
// Before: Complex method hard to test
public Order processOrder(OrderRequest request) {
  // Validation, discount calculation, payment, inventory, notification...
  // 50+ lines of mixed concerns
}

// After: Refactored into testable units
public Order processOrder(OrderRequest request) {
  validateOrder(request);
  var order = createOrder(request);
  applyDiscount(order);
  processPayment(order);
  updateInventory(order);
  sendNotification(order);
  return order;
}
当方法或类过于复杂而难以有效测试时:
  1. 分析复杂度 - 如果需要5-7个以上的测试用例才能覆盖单个方法,它可能过于复杂
  2. 建议重构 - 建议将代码拆分为更小、聚焦的函数
  3. 用户决策 - 如果用户同意重构,帮助识别提取点
  4. 必要时继续 - 如果用户决定保留复杂代码,仍需实现测试,尽管难度较大
重构建议示例:
java
// Before: Complex method hard to test
public Order processOrder(OrderRequest request) {
  // Validation, discount calculation, payment, inventory, notification...
  // 50+ lines of mixed concerns
}

// After: Refactored into testable units
public Order processOrder(OrderRequest request) {
  validateOrder(request);
  var order = createOrder(request);
  applyDiscount(order);
  processPayment(order);
  updateInventory(order);
  sendNotification(order);
  return order;
}

Avoid Code Redundancy

避免代码冗余

Create helper methods for commonly used objects and mock setup to enhance readability and maintainability.
创建常用对象和模拟设置的辅助方法,以提升可读性和可维护性。

Test Organization with @DisplayName

使用@DisplayName组织测试

Use descriptive display names to clarify test intent:
java
@Test
@DisplayName("Should calculate discount for VIP customer")
void shouldCalculateDiscountForVip() { }

@Test
@DisplayName("Should reject order when customer has insufficient credit")
void shouldRejectOrderForInsufficientCredit() { }
使用描述性的显示名称明确测试意图:
java
@Test
@DisplayName("Should calculate discount for VIP customer")
void shouldCalculateDiscountForVip() { }

@Test
@DisplayName("Should reject order when customer has insufficient credit")
void shouldRejectOrderForInsufficientCredit() { }

Test Coverage Order

测试覆盖顺序

Always structure tests in this order:
  1. Main scenario - The happy path, most common use case
  2. Other paths - Alternative valid scenarios, edge cases
  3. Exceptions/Errors - Invalid inputs, error conditions, failure modes
始终按以下顺序组织测试:
  1. 主场景 - 正常路径,最常见的用例
  2. 其他路径 - 其他有效场景、边缘情况
  3. 异常/错误 - 无效输入、错误条件、故障模式

Test Production Scenarios

测试生产场景

Write tests with real production scenarios in mind. This makes tests more relatable and helps understand code behavior in actual production cases.
结合真实生产场景编写测试。这会让测试更贴合实际,有助于理解代码在真实生产环境中的行为。

Test Coverage Goals

测试覆盖率目标

Aim for 80% code coverage as a practical balance between quality and effort. Higher coverage is beneficial but not the only goal.
Use Jacoco maven plugin for coverage reporting and tracking.
Coverage Rules:
  • 80+% coverage minimum
  • Focus on meaningful assertions, not just execution
What to Prioritize:
  1. Business-critical paths (payment processing, order validation)
  2. Complex algorithms (pricing, discount calculations)
  3. Error handling (exceptions, edge cases)
  4. Integration points (external APIs, databases)
将80%的代码覆盖率作为质量与投入之间的实际平衡点。更高的覆盖率有益,但并非唯一目标。
使用Jacoco Maven插件进行覆盖率报告和跟踪。
覆盖率规则:
  • 最低80%+覆盖率
  • 聚焦有意义的断言,而非仅执行代码
优先覆盖内容:
  1. 业务关键路径(支付处理、订单验证)
  2. 复杂算法(定价、折扣计算)
  3. 错误处理(异常、边缘情况)
  4. 集成点(外部API、数据库)

Dependencies (Spring Boot 4)

依赖(Spring Boot 4)

xml
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>

<!-- For WebMvc tests -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webmvc-test</artifactId>
  <scope>test</scope>
</dependency>

<!-- For Testcontainers -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-testcontainers</artifactId>
  <scope>test</scope>
</dependency>
xml
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>

<!-- For WebMvc tests -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webmvc-test</artifactId>
  <scope>test</scope>
</dependency>

<!-- For Testcontainers -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-testcontainers</artifactId>
  <scope>test</scope>
</dependency>