spring-boot-test-patterns by giuseppe-trisciuoglio/developer-kit
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill spring-boot-test-patterns使用 JUnit 5、Mockito、Testcontainers 和性能优化的切片测试模式为 Spring Boot 应用程序编写健壮测试套件的全面指南。
@WebMvcTest 或 MockMvc 测试 REST API@ServiceConnection 以进行容器管理| 测试类型 | 注解 | 目标耗时 | 用例 |
|---|---|---|---|
| 单元测试 | @ExtendWith(MockitoExtension.class) | < 50ms | 无需 Spring 上下文的业务逻辑 |
| 存储库测试 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
@DataJpaTest| < 100ms |
| 最小化上下文的数据库操作 |
| 控制器测试 | @WebMvcTest / @WebFluxTest | < 100ms | REST API 层测试 |
| 集成测试 | @SpringBootTest | < 500ms | 包含容器的完整应用程序上下文 |
| Testcontainers | @ServiceConnection / @Testcontainers | 可变 | 真实数据库/消息代理容器 |
Spring Boot 测试:
@SpringBootTest — 完整的应用程序上下文(谨慎使用)@DataJpaTest — 仅 JPA 组件(存储库、实体)@WebMvcTest — 仅 MVC 层(控制器、@ControllerAdvice)@WebFluxTest — 仅 WebFlux 层(响应式控制器)@JsonTest — 仅 JSON 序列化组件Testcontainers:
@ServiceConnection — 将 Testcontainer 连接到 Spring Boot (3.5+)@DynamicPropertySource — 在运行时注册动态属性@Testcontainers — 启用 Testcontainers 生命周期管理使用模拟依赖项测试业务逻辑:
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void shouldFindUserByIdWhenExists() {
when(userRepository.findById(1L)).thenReturn(Optional.of(user));
Optional<User> result = userService.findById(1L);
assertThat(result).isPresent();
verify(userRepository).findById(1L);
}
}
有关高级模式,请参阅 unit-testing.md。
针对特定层使用聚焦的测试切片:
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestContainerConfig
class UserRepositoryIntegrationTest {
@Autowired
private UserRepository userRepository;
@Test
void shouldSaveAndRetrieveUser() {
User saved = userRepository.save(user);
assertThat(userRepository.findByEmail("test@example.com")).isPresent();
}
}
有关所有切片模式,请参阅 slice-testing.md。
使用 MockMvc 测试控制器:
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@Test
void shouldGetUserById() throws Exception {
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.email").value("test@example.com"));
}
}
@ServiceConnection 的 Testcontainers使用 Spring Boot 3.5+ 配置容器:
@TestConfiguration
public class TestContainerConfig {
@Bean
@ServiceConnection
public PostgreSQLContainer<?> postgresContainer() {
return new PostgreSQLContainer<>("postgres:16-alpine");
}
}
在测试类上使用 @Import(TestContainerConfig.class) 应用。有关详细配置,请参阅 testcontainers-setup.md。
包含所需的测试依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.19.0</version>
<scope>test</scope>
</dependency>
有关完整的依赖项列表,请参阅 test-dependencies.md。
为自动化测试设置 GitHub Actions:
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
docker:
image: docker:20-dind
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
- name: Run tests
run: ./mvnw test
有关完整的 CI/CD 模式,请参阅 ci-cd-configuration.md。
实现测试后,请验证:
docker ps(查找 testcontainer 镜像)@ServiceConnection 的完整集成测试@SpringBootTest
@Import(TestContainerConfig.class)
class OrderServiceIntegrationTest {
@Autowired
private OrderService orderService;
@Autowired
private UserRepository userRepository;
@Test
void shouldCreateOrderForExistingUser() {
User user = userRepository.save(User.builder()
.email("order-test@example.com")
.build());
Order order = orderService.createOrder(user.getId(), List.of(
new OrderItem("SKU-001", 2)
));
assertThat(order.getId()).isNotNull();
assertThat(order.getStatus()).isEqualTo(OrderStatus.PENDING);
}
}
@DataJpaTest@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestContainerConfig
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void shouldFindByEmail() {
userRepository.save(User.builder()
.email("jpa-test@example.com")
.build());
assertThat(userRepository.findByEmail("jpa-test@example.com"))
.isPresent();
}
}
有关完整的端到端示例,请参阅 workflow-patterns.md。
@DataJpaTest,控制器使用 @WebMvcTest,仅完整集成测试使用 @SpringBootTest@ServiceConnection:在 Spring Boot 3.5+ 上,相比 @DynamicPropertySource,它能提供更清晰的容器管理@BeforeEach 中显式初始化所有测试数据withReuse(true) + TESTCONTAINERS_REUSE_ENABLE=true)@DirtiesContext:强制重建上下文,显著影响性能@DirtiesContext(强制重建上下文)@MockBean(会创建独立的上下文)@TestPropertySource(会创建独立的上下文)@SpringBootTest 进行单元测试;应使用普通的 Mockito@MockBean 配置可能会使上下文缓存失效每周安装量
533
代码仓库
GitHub 星标数
174
首次出现
2026年2月3日
安全审计
安装于
gemini-cli426
opencode426
codex420
cursor407
github-copilot400
claude-code391
Comprehensive guidance for writing robust test suites for Spring Boot applications using JUnit 5, Mockito, Testcontainers, and performance-optimized slice testing patterns.
@WebMvcTest or MockMvc@ServiceConnection for container management in Spring Boot 3.5+| Test Type | Annotation | Target Time | Use Case |
|---|---|---|---|
| Unit Tests | @ExtendWith(MockitoExtension.class) | < 50ms | Business logic without Spring context |
| Repository Tests | @DataJpaTest | < 100ms | Database operations with minimal context |
| Controller Tests | @WebMvcTest / @WebFluxTest | < 100ms | REST API layer testing |
| Integration Tests | @SpringBootTest | < 500ms | Full application context with containers |
| Testcontainers | @ServiceConnection / @Testcontainers | Varies | Real database/message broker containers |
Spring Boot Test:
@SpringBootTest — Full application context (use sparingly)@DataJpaTest — JPA components only (repositories, entities)@WebMvcTest — MVC layer only (controllers, @ControllerAdvice)@WebFluxTest — WebFlux layer only (reactive controllers)@JsonTest — JSON serialization components onlyTestcontainers:
@ServiceConnection — Wire Testcontainer to Spring Boot (3.5+)@DynamicPropertySource — Register dynamic properties at runtime@Testcontainers — Enable Testcontainers lifecycle managementTest business logic with mocked dependencies:
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void shouldFindUserByIdWhenExists() {
when(userRepository.findById(1L)).thenReturn(Optional.of(user));
Optional<User> result = userService.findById(1L);
assertThat(result).isPresent();
verify(userRepository).findById(1L);
}
}
See unit-testing.md for advanced patterns.
Use focused test slices for specific layers:
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestContainerConfig
class UserRepositoryIntegrationTest {
@Autowired
private UserRepository userRepository;
@Test
void shouldSaveAndRetrieveUser() {
User saved = userRepository.save(user);
assertThat(userRepository.findByEmail("test@example.com")).isPresent();
}
}
See slice-testing.md for all slice patterns.
Test controllers with MockMvc:
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@Test
void shouldGetUserById() throws Exception {
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.email").value("test@example.com"));
}
}
@ServiceConnectionConfigure containers with Spring Boot 3.5+:
@TestConfiguration
public class TestContainerConfig {
@Bean
@ServiceConnection
public PostgreSQLContainer<?> postgresContainer() {
return new PostgreSQLContainer<>("postgres:16-alpine");
}
}
Apply with @Import(TestContainerConfig.class) on test classes. See testcontainers-setup.md for detailed configuration.
Include required testing dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.19.0</version>
<scope>test</scope>
</dependency>
See test-dependencies.md for complete dependency list.
Set up GitHub Actions for automated testing:
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
docker:
image: docker:20-dind
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
- name: Run tests
run: ./mvnw test
See ci-cd-configuration.md for full CI/CD patterns.
After implementing tests, verify:
docker ps (look for testcontainer images)@ServiceConnection@SpringBootTest
@Import(TestContainerConfig.class)
class OrderServiceIntegrationTest {
@Autowired
private OrderService orderService;
@Autowired
private UserRepository userRepository;
@Test
void shouldCreateOrderForExistingUser() {
User user = userRepository.save(User.builder()
.email("order-test@example.com")
.build());
Order order = orderService.createOrder(user.getId(), List.of(
new OrderItem("SKU-001", 2)
));
assertThat(order.getId()).isNotNull();
assertThat(order.getStatus()).isEqualTo(OrderStatus.PENDING);
}
}
@DataJpaTest with Real Database@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestContainerConfig
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void shouldFindByEmail() {
userRepository.save(User.builder()
.email("jpa-test@example.com")
.build());
assertThat(userRepository.findByEmail("jpa-test@example.com"))
.isPresent();
}
}
See workflow-patterns.md for complete end-to-end examples.
@DataJpaTest for repositories, @WebMvcTest for controllers, @SpringBootTest only for full integration@ServiceConnection on Spring Boot 3.5+ for cleaner container management over @DynamicPropertySource@BeforeEachwithReuse(true) + TESTCONTAINERS_REUSE_ENABLE=true)@DirtiesContext unless absolutely necessary (forces context rebuild)@MockBean with different configurations (creates separate contexts)@TestPropertySource (creates separate contexts)@SpringBootTest for unit tests; use plain Mockito instead@MockBean configurationsWeekly Installs
533
Repository
GitHub Stars
174
First Seen
Feb 3, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
gemini-cli426
opencode426
codex420
cursor407
github-copilot400
claude-code391
Vue.js测试最佳实践:Vue 3组件、组合式函数、Pinia与异步测试完整指南
3,700 周安装
FlowStudio MCP 构建部署 Power Automate 云流指南 | 自动化流程开发
530 周安装
mcp2cli:无需代码,将MCP/OpenAPI/GraphQL实时转换为命令行工具
530 周安装
交互式作品集设计指南:30秒吸引招聘者,提升作品集转化率与个人品牌
530 周安装
每日销售简报AI工具 - 自动生成优先级行动计划,整合日历、CRM和邮件数据
531 周安装
生产排程实战指南:离散制造工厂的有限产能排程、换线优化与瓶颈管理
531 周安装
Angular 21 最佳实践指南:TypeScript、Signals、组件与性能优化
531 周安装
@DirtiesContext: Forces context rebuild, significantly hurts performance