Provides comprehensive testing patterns for Spring Boot applications covering unit, integration, slice, and container-based testing with JUnit 5, Mockito, Testcontainers, and performance optimization. Use when writing tests, @Test methods, @MockBean mocks, or implementing test suites for Spring Boot applications.
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill spring-boot-test-patterns
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("[email protected]")).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("[email protected]"));
}
}
@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("[email protected]")
.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("[email protected]")
.build());
assertThat(userRepository.findByEmail("[email protected]"))
.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: Forces context rebuild, significantly hurts performance@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 configurationsToolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
Use when implementing any feature or bugfix, before writing implementation code
Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes
Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always
Expert guidance for systematic backtesting of trading strategies. Use when developing, testing, stress-testing, or validating quantitative trading strategies. Covers "beating ideas to death" methodology, parameter robustness testing, slippage modeling, bias prevention, and interpreting backtest results. Applicable when user asks about backtesting, strategy validation, robustness testing, avoiding overfitting, or systematic trading development.
Cloud laboratory platform for automated protein testing and validation. Use when designing proteins and needing experimental validation including binding assays, expression testing, thermostability measurements, enzyme activity assays, or protein sequence optimization. Also use for submitting experiments via API, tracking experiment status, downloading results, optimizing protein sequences for better expression using computational tools (NetSolP, SoluProt, SolubleMPNN, ESM), or managing protein design workflows with wet-lab validation.
This skill should be used for time series machine learning tasks including classification, regression, clustering, forecasting, anomaly detection, segmentation, and similarity search. Use when working with temporal data, sequential patterns, or time-indexed observations requiring specialized algorithms beyond standard ML approaches. Particularly suited for univariate and multivariate time series analysis with scikit-learn compatible APIs.
Take giuseppe-trisciuoglio/spring-boot-test-patterns from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.