CtrlK
BlogDocsLog inGet started
Tessl Logo

giuseppe-trisciuoglio/developer-kit

Comprehensive developer toolkit providing reusable skills for Java/Spring Boot, TypeScript/NestJS/React/Next.js, Python, PHP, AWS CloudFormation, AI/RAG, DevOps, and more.

89

Quality

89%

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Risky

Do not use without reviewing

Overview
Quality
Evals
Security
Files

devkit.java.write-integration-tests.mdplugins/developer-kit-java/commands/

allowed-tools:
Read, Write, Bash, Grep, Glob
argument-hint:
[class-path]
description:
Generates comprehensive integration tests for Spring Boot classes using Testcontainers (PostgreSQL, Redis, MongoDB) with `@ServiceConnection` pattern. Use when writing integration tests for service or repository classes.
model:
inherit

Write Integration Tests for Spring Boot

Overview

Generates comprehensive integration tests for Spring Boot classes using Testcontainers (PostgreSQL, Redis, MongoDB) with @ServiceConnection pattern. Use when writing integration tests for service or repository classes.

You are tasked with generating a complete integration test for the Java class specified in $1.

Usage

When analyzing the target class, Claude will automatically reference these skills to:

  • Determine the appropriate test strategy based on layer (Controller/Service/Repository)
  • Select the correct Testcontainers based on dependencies
  • Apply framework-specific testing patterns
  • Generate comprehensive test scenarios covering all edge cases
  • Use @MockitoBean for mocking dependencies (replaces deprecated @MockBean)

Arguments

ArgumentDescription
$ARGUMENTSCombined arguments passed to the command

Execution Instructions

Agent Selection: To execute this task, use the following agent with fallback:

  • Primary: developer-kit-java:spring-boot-unit-testing-expert
  • If not available: Use developer-kit-java:spring-boot-unit-testing-expert or fallback to general-purpose agent with spring-boot-test-patterns skill

Process

1. Analyze Target Class

  • Read the class file from $1
  • Identify the layer (Controller, Service, Repository)
  • Detect dependencies (Database, Cache, Message Queue, etc.)
  • Identify external integrations

2. Determine Required Testcontainers

Based on dependencies, include:

  • PostgreSQL: For JPA repositories or database operations
  • Redis: For caching or session management
  • MongoDB: For NoSQL operations
  • RabbitMQ/Kafka: For messaging operations
  • Additional containers: Based on specific dependencies

3. Generate Integration Test

Follow these patterns from the spring-boot-test-patterns skill:

Test Structure

@SpringBootTest
@Testcontainers class

<ClassName> IntegrationTest {

    @Container
    @ServiceConnection
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(
            DockerImageName.parse("postgres:16-alpine"))
            .withDatabaseName("testdb")
            .withUsername("test")
            .withPassword("test");

    @Container
    @ServiceConnection
    static GenericContainer<?> redis = new GenericContainer<>(
            DockerImageName.parse("redis:7-alpine"))
            .withExposedPorts(6379);

    @Autowired
    private <TargetClass > targetClass;

    @Test
    void shouldPerformIntegrationScenario () {
        // Test implementation
    }
}

Key Requirements

  1. Use @ServiceConnection for Spring Boot 3.5+ automatic wiring
  2. Static containers for reuse across test methods
  3. Minimal context loading - only load what's needed
  4. Real dependencies via Testcontainers
  5. Complete scenarios - test full workflows
  6. Proper assertions - use AssertJ for fluent assertions
  7. Use @MockitoBean (not deprecated @MockBean) from org.springframework.test.context.bean.override.mockito

Container Selection Guidelines

  • @Repository/@DataJpaTest: PostgreSQL/MySQL container
  • @Service with caching: Redis container
  • @RestController: MockMvc + required backend containers
  • Message consumers/producers: RabbitMQ/Kafka container
  • MongoDB repositories: MongoDB container

4. Dependencies Check

Verify and add required dependencies:

Maven:

<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>
// Use latest stable version
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>1.19.0</version>
// Use latest stable version
<scope>test</scope>
</dependency>

Gradle:

testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.testcontainers:junit-jupiter:1.19.0")
testImplementation("org.testcontainers:postgresql:1.19.0")

5. Test Coverage

Generate tests covering:

  • ✅ Happy path scenarios
  • ✅ Edge cases and boundary conditions
  • ✅ Error handling and validation
  • ✅ Transaction rollback scenarios
  • ✅ Concurrent access patterns (if applicable)

6. Performance Optimization

  • Use static containers for JVM-level reuse
  • Avoid @DirtiesContext unless absolutely necessary
  • Group tests with similar configuration
  • Target: < 500ms per integration test

Example Patterns

Controller Integration Test

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Testcontainers
class UserControllerIntegrationTest {

    @Container
    @ServiceConnection
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(
            DockerImageName.parse("postgres:16-alpine"));

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    void shouldCreateAndRetrieveUser() {
        UserRequest request = new UserRequest("john@example.com", "John Doe");

        ResponseEntity<UserResponse> createResponse = restTemplate
                .postForEntity("/api/users", request, UserResponse.class);

        assertThat(createResponse.getStatusCode()).isEqualTo(HttpStatus.CREATED);
        assertThat(createResponse.getBody()).isNotNull();

        Long userId = createResponse.getBody().id();

        ResponseEntity<UserResponse> getResponse = restTemplate
                .getForEntity("/api/users/" + userId, UserResponse.class);

        assertThat(getResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(getResponse.getBody().email()).isEqualTo("john@example.com");
    }
}

Controller with Mocked Service

import org.springframework.test.context.bean.override.mockito.MockitoBean;

@WebMvcTest(UserController.class)
@Testcontainers
class UserControllerMockTest {

    @Autowired
    private MockMvc mockMvc;

    @MockitoBean  // Use @MockitoBean instead of deprecated @MockBean
    private UserService userService;

    @Test
    void shouldReturnUserWhenExists() throws Exception {
        User user = new User(1L, "john@example.com", "John Doe");
        when(userService.findById(1L)).thenReturn(Optional.of(user));

        mockMvc.perform(get("/api/users/1"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.email").value("john@example.com"));
    }
}

Service with Cache Integration Test

@SpringBootTest
@Testcontainers
class UserServiceIntegrationTest {

    @Container
    @ServiceConnection
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(
            DockerImageName.parse("postgres:16-alpine"));

    @Container
    @ServiceConnection
    static GenericContainer<?> redis = new GenericContainer<>(
            DockerImageName.parse("redis:7-alpine"))
            .withExposedPorts(6379);

    @Autowired
    private UserService userService;

    @Autowired
    private CacheManager cacheManager;

    @Test
    void shouldCacheUserAfterFirstRetrieval() {
        User user = userService.createUser("test@example.com", "Test User");

        // First call - hits database
        User firstCall = userService.findById(user.getId());
        assertThat(firstCall).isNotNull();

        // Verify cached
        Cache userCache = cacheManager.getCache("users");
        assertThat(userCache.get(user.getId())).isNotNull();

        // Second call - hits cache
        User secondCall = userService.findById(user.getId());
        assertThat(secondCall).isEqualTo(firstCall);
    }
}

Repository Integration Test

@DataJpaTest
@Testcontainers
class UserRepositoryIntegrationTest {

    @Container
    @ServiceConnection
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(
            DockerImageName.parse("postgres:16-alpine"));

    @Autowired
    private UserRepository userRepository;

    @Test
    void shouldFindUsersByEmailDomain() {
        userRepository.save(new User("john@example.com", "John"));
        userRepository.save(new User("jane@example.com", "Jane"));
        userRepository.save(new User("bob@another.com", "Bob"));

        List<User> exampleUsers = userRepository.findByEmailEndingWith("@example.com");

        assertThat(exampleUsers).hasSize(2);
        assertThat(exampleUsers)
                .extracting(User::getEmail)
                .containsExactlyInAnyOrder("john@example.com", "jane@example.com");
    }
}

Output

  1. Create test file in src/test/java matching package structure
  2. Name: <ClassName>IntegrationTest.java
  3. Include all necessary imports
  4. Add appropriate Testcontainers based on dependencies
  5. Implement comprehensive test scenarios
  6. Add comments explaining complex scenarios

Verification

After generating the test:

  1. Verify all imports are correct
  2. Check Testcontainer versions match project dependencies
  3. Ensure @ServiceConnection is used (Spring Boot 3.5+)
  4. Validate test completeness against requirements
  5. Run the test: ./mvnw test -Dtest=<ClassName>IntegrationTest

Best Practices

  • ✅ Use static containers for performance
  • ✅ Prefer @ServiceConnection over @DynamicPropertySource
  • ✅ Use @MockitoBean instead of deprecated @MockBean (from org.springframework.test.context.bean.override.mockito)
  • ✅ Test complete workflows, not isolated methods
  • ✅ Use meaningful test method names describing scenarios
  • ✅ Add @Transactional on test methods for automatic rollback
  • ✅ Use AssertJ for fluent, readable assertions
  • ❌ Avoid @DirtiesContext unless absolutely necessary
  • ❌ Don't mix unit test patterns in integration tests
  • ❌ Don't hardcode ports or URLs

Available Skills Reference

This command leverages the following skills available in the repository:

Testing Skills

  • spring-boot-test-patterns - Core integration testing patterns with Testcontainers and @ServiceConnection
  • unit-test-controller-layer - REST controller testing with MockMvc
  • unit-test-service-layer - Service layer testing with Mockito
  • unit-test-caching - Testing cache behaviors with Redis
  • unit-test-json-serialization - Testing JSON serialization/deserialization
  • unit-test-exception-handler - Testing @ControllerAdvice exception handlers
  • unit-test-wiremock-rest-api - Testing external REST APIs with WireMock
  • unit-test-scheduled-async - Testing @Scheduled and @Async methods
  • unit-test-security-authorization - Testing Spring Security and authorization

Spring Boot Skills

  • spring-boot-rest-api-standards - REST API design patterns to test
  • spring-boot-crud-patterns - CRUD operation patterns to test
  • spring-boot-cache - Caching strategies with Spring Cache
  • spring-boot-dependency-injection - Constructor injection patterns
  • spring-boot-event-driven-patterns - Event-driven architecture testing
  • spring-data-jpa - JPA repository patterns

Important Notes

  • @MockitoBean vs @MockBean: Spring Framework 6.2+ introduces @MockitoBean from org.springframework.test.context.bean.override.mockito package. The old @MockBean from org.springframework.boot.test.mock.mockito is deprecated.
  • Package import: Always use import org.springframework.test.context.bean.override.mockito.MockitoBean;
  • **Reference **: Spring Framework MockitoBean Documentation

Target class: $ARGUMENTS

Analyze the class and generate a comprehensive integration test following the patterns above.

Examples

/devkit.java.write-integration-tests example-input

plugins

developer-kit-java

README.md

CHANGELOG.md

context7.json

CONTRIBUTING.md

README_CN.md

README_ES.md

README_IT.md

README.md

tessl.json

tile.json