Skip to main content
skill CX Codex

spring-boot-test-patterns — Claude Code skill: Spring Boot tests

A skill that gives your agent ready patterns for Spring Boot tests: Mockito unit tests, @DataJpaTest and @WebMvcTest slices, Testcontainers integration.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add giuseppe-trisciuoglio/developer-kit --skill spring-boot-test-patterns -a claude-code
Open on GitHub

What spring-boot-test-patterns does

The skill hands your agent a set of Spring Boot testing patterns, split by layer. Unit tests cover business logic with mocked dependencies via @ExtendWith(MockitoExtension.class). Slice tests keep the context small: @DataJpaTest for repositories, @WebMvcTest and @WebFluxTest for controllers, @JsonTest for serialization. Full @SpringBootTest is reserved for integration work. Each type comes with a target time: under 50 ms for unit, under 100 ms for slices, under 500 ms for integration.

Testcontainers get their own section. A container is declared as a bean with @ServiceConnection on Spring Boot 3.5+, then pulled in with @Import(TestContainerConfig.class); older versions use @DynamicPropertySource. The examples use PostgreSQLContainer with the postgres:16-alpine image. You also get the dependency block for pom.xml — spring-boot-starter-test plus org.testcontainers:junit-jupiter at 1.19.0 — and a GitHub Actions job that runs ./mvnw test on JDK 17.

Docker has to be running, otherwise the container examples go nowhere. docker ps is the quick check: if the testcontainer images show up, you are fine. The skill also suggests running tests one at a time to catch state leaking between them.

What it helps with

  • write a service unit test with a mocked repository
  • spin up a real database in a test with Testcontainers
  • test a REST controller without loading the full context
  • pick between @DataJpaTest and @SpringBootTest
  • run the test suite in GitHub Actions

Example prompts for the agent

  • Write tests for OrderService using the spring-boot-test-patterns patterns
  • Add a @DataJpaTest with Testcontainers for UserRepository
  • Review my tests for isolation and flag where the Spring context is unnecessary

How to install spring-boot-test-patterns

1Skills CLI (Vercel)

npx skills add giuseppe-trisciuoglio/developer-kit --skill spring-boot-test-patterns -a claude-code

2Manually: put the files in place

~/.claude/skills/spring-boot-test-patterns/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/spring-boot-test-patterns/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about spring-boot-test-patterns

How do I install spring-boot-test-patterns in Claude?

Run npx skills add giuseppe-trisciuoglio/developer-kit --skill spring-boot-test-patterns -a claude-code. The skill file then lives at ~/.claude/skills/spring-boot-test-patterns/SKILL.md.

What does spring-boot-test-patterns do?

It gives the agent Spring Boot testing patterns: Mockito unit tests, context slices, Testcontainers integration tests and the dependency setup.

What do the Testcontainers examples need to run?

A running Docker daemon, since containers start during the test. @ServiceConnection requires Spring Boot 3.5 or newer; older versions use @DynamicPropertySource.

Source text

SKILL.md · MIT
---
name: spring-boot-test-patterns
description: 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.
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
---

# Spring Boot Testing Patterns

## Overview

Comprehensive guidance for writing robust test suites for Spring Boot applications using JUnit 5, Mockito, Testcontainers, and performance-optimized slice testing patterns.

## When to Use

- Writing unit tests for services or repositories with mocked dependencies
- Implementing integration tests with real databases via Testcontainers
- Testing REST APIs with `@WebMvcTest` or MockMvc
- Configuring `@ServiceConnection` for container management in Spring Boot 3.5+

## Quick Reference

| 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 |

## Core Concepts

### Test Architecture Philosophy

1. **Unit Tests** — Fast, isolated tests without Spring context (< 50ms)
2. **Slice Tests** — Minimal Spring context for specific layers (< 100ms)
3. **Integration Tests** — Full Spring context with real dependencies (< 500ms)

### Key Annotations

**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 only

**Testcontainers:**
- `@ServiceConnection` — Wire Testcontainer to Spring Boot (3.5+)
- `@DynamicPropertySource` — Register dynamic properties at runtime
- `@Testcontainers` — Enable Testcontainers lifecycle management

## Instructions

### 1. Unit Testing Pattern

Test business logic with mocked dependencies:

```java
@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](references/unit-testing.md) for advanced patterns.

### 2. Slice Testing Pattern

Use focused test slices for specific layers:

```java
@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](references/slice-testing.md) for all slice patterns.

### 3. REST API Testing Pattern

Test controllers with MockMvc:

```java
@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]"));
    }
}
```

### 4. Testcontainers with `@ServiceConnection`

Configure containers with Spring Boot 3.5+:

```java
@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](references/testcontainers-setup.md) for detailed configuration.

### 5. Add Dependencies

Include required testing dependencies:

```xml
<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](references/test-dependencies.md) for complete dependency list.

### 6. Configure CI/CD

Set up GitHub Actions for automated testing:

```yaml
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](references/ci-cd-configuration.md) for full CI/CD patterns.

### Validation Checkpoints

After implementing tests, verify:
- Container running: `docker ps` (look for testcontainer images)
- Context loaded: check startup logs for "Started Application in X.XX seconds"
- Test isolation: run tests individually and confirm no cross-contamination

## Examples

### Full Integration Test with `@ServiceConnection`

```java
@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

```java
@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](references/workflow-patterns.md) for complete end-to-end examples.

## Best Practices

- **Use the right test type**: `@DataJpaTest` for repositories, `@WebMvcTest` for controllers, `@SpringBootTest` only for full integration
- **Prefer `@ServiceConnection`** on Spring Boot 3.5+ for cleaner container management over `@DynamicPropertySource`
- **Keep tests deterministic**: Initialize all test data explicitly in `@BeforeEach`
- **Organize by layer**: Group tests by layer to maximize context caching
- **Reuse Testcontainers** at JVM level (`withReuse(true)` + `TESTCONTAINERS_REUSE_ENABLE=true`)
- **Avoid `@DirtiesContext`**: Forces context rebuild, significantly hurts performance
- **Mock external services**, use real databases only when necessary
- **Performance targets**: Unit < 50ms, Slice < 100ms, Integration < 500ms

## Constraints and Warnings

- Never use `@DirtiesContext` unless absolutely necessary (forces context rebuild)
- Avoid mixing `@MockBean` with different configurations (creates separate contexts)
- Testcontainers require Docker; ensure CI/CD pipelines have Docker support
- Do not rely on test execution order; each test must be independent
- Be cautious with `@TestPropertySource` (creates separate contexts)
- Do not use `@SpringBootTest` for unit tests; use plain Mockito instead
- Context caching can be invalidated by different `@MockBean` configurations
- Avoid static mutable state in tests (causes flaky tests)

## References

- **[test-dependencies.md](references/test-dependencies.md)** — Maven/Gradle test dependencies
- **[unit-testing.md](references/unit-testing.md)** — Unit testing with Mockito patterns
- **[slice-testing.md](references/slice-testing.md)** — Repository, controller, and JSON slice tests
- **[testcontainers-setup.md](references/testcontainers-setup.md)** — Testcontainers configuration patterns
- **[ci-cd-configuration.md](references/ci-cd-configuration.md)** — GitHub Actions, GitLab CI, Docker Compose
- **[api-reference.md](references/api-reference.md)** — Complete test annotations and utilities
- **[best-practices.md](references/best-practices.md)** — Testing patterns and optimization
- **[workflow-patterns.md](references/workflow-patterns.md)** — Complete integration test examples

© giuseppe-trisciuoglio · MIT · giuseppe-trisciuoglio/developer-kit

Similar skills

All skills for Testing and QA →

From the same set96

nextjs-performance A Next.js optimization skill: Core Web Vitals, images and fonts, caching, streaming, bundle size. Useful when pages feel slow and you need a starting point. CX Codex +1 4,900installs unit-test-bean-validation Provides patterns for testing Jakarta Bean Validation constraints and custom validators in JUnit 5. Helps verify DTO logic without loading Spring context. CX Codex +1 4,900installs react-patterns Teaches your agent React 19 and Next.js App Router patterns: Server Components, Server Actions, useOptimistic, Suspense boundaries. Useful when the app is already on React 19. CX Codex +1 4,800installs tailwind-design-system Creates and orchestrates a design system using Tailwind CSS v4.1+ and shadcn/ui. It defines oklch design tokens, themes via CSS variables, and wraps UI primitives. CX Codex +1 4,500installs react-code-review Reviews React components and hooks before merge: composition, hook dependencies, accessibility, TypeScript types. Findings come sorted by severity. CX Codex +1 4,300installs spring-boot-rest-api-standards Enforces REST API design standards for Spring Boot, covering URL structure, DTO validation, status codes, and global exception handling. CX Codex +1 4,200installs typescript-docs Creates TypeScript documentation with JSDoc, TypeDoc, and ADRs. Use it when documenting APIs, architecture choices, or framework-specific code. CX Codex +1 4,200installs nestjs Gives your agent NestJS patterns: CRUD modules, JWT guards, Drizzle schemas and migrations. Handy when you are building an API on NestJS. CX Codex +1 4,200installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor