| name | generate-integration-tests |
| description | Generate integration tests for a Java class using Testcontainers. Supports Spring Boot (3.1+), Quarkus (3.0+), and Micronaut (4.0+). Detects class type (repository, controller, service) and applies framework-appropriate test patterns. Requires Java 17+.
|
| argument-hint | [path-to-java-class] |
| disable-model-invocation | true |
| allowed-tools | Read Write Edit Glob Grep |
Generate Integration Tests
Purpose
This skill generates a comprehensive integration test class for a given Java source file. It detects the project's framework (Spring Boot, Quarkus, or Micronaut), identifies the class type (repository, controller, or service), and produces framework-appropriate integration tests using Testcontainers for real database and external service containers.
Usage
/generate-integration-tests <path-to-java-class>
Argument: $ARGUMENTS — the file path (relative or absolute) to the target .java source file. Required; no default.
Examples
/generate-integration-tests src/main/java/com/example/repository/OrderRepository.java
Generates src/test/java/com/example/repository/integration/OrderRepositoryTest.java with Testcontainers database setup, application context bootstrap, and test methods for each repository method.
Expected Output
For a Spring Boot repository with a PostgreSQL database, the skill generates a test class with @SpringBootTest, @Testcontainers, @ServiceConnection on a PostgreSQLContainer, @BeforeEach for data cleanup, and @Nested inner classes grouping tests by method with shouldBehaviorWhenCondition naming and Arrange-Act-Assert structure.
Behavior Summary
| Class Type | Detection Signal | Test Strategy |
|---|
| Repository | Extends JpaRepository/CrudRepository/PanacheRepository; @Repository annotation | Database container, CRUD + custom query tests |
| Controller | @RestController/@Controller (Spring), @Path (Quarkus), @Controller (Micronaut) | Full-stack boot, HTTP endpoint tests (MockMvc / RestAssured / HttpClient) |
| Service | @Service/@Component/@ApplicationScoped/@Singleton with external dependencies | Testcontainers for Kafka/Redis/RabbitMQ, WireMock for HTTP |
| No integration points | None of the above | Rejected — suggest /generate-unit-tests |
Prerequisites
- A Java 17+ project with one of: Spring Boot 3.1+, Quarkus 3.0+, or Micronaut 4.0+
- For Testcontainers-based tests: Docker available on the developer's machine
- For H2 in-memory default: no Docker required
Instructions
You are generating an integration test class for a Java source file. Follow each step below in order.
Step 1: Read and Validate the Target Class
Read the file at $ARGUMENTS.
If no argument is provided, inform the user:
"Please provide a path to a Java source file. Usage: /generate-integration-tests path/to/MyClass.java"
Then stop.
If the file does not exist, inform the user:
"File not found: {path}. Please verify the path and try again."
Then stop.
If the file is not a .java file, inform the user:
"Expected a .java file but got {extension}. Please provide a Java source file."
Then stop.
Analyze the class and extract:
- Package name: From the
package declaration
- Class name: The simple class name
- Class kind:
class, interface, record, or enum
- Interfaces are allowed ONLY if they are repository interfaces (extend a framework repository base). Other interfaces → inform user and stop.
- Abstract classes → inform user: "Integration tests require a concrete class or repository interface." Then stop.
- Public methods: All public methods with name, return type, parameter types/names/annotations, declared exceptions
- Dependencies: Constructor-injected and field-injected dependencies (type + name)
Step 2: Detect Build Tool
Scan the project for build files:
- Look for
pom.xml (Maven)
- Look for
build.gradle or build.gradle.kts (Gradle)
If both exist: Ask the user which build tool to use.
If neither exists: Inform the user that no supported build file was found and stop.
Record the build tool type and all build file paths (root + child modules for multi-module projects).
Step 3: Detect Framework
Read reference/framework-detection.md now for the complete detection matrix and procedure.
Scan the build files for framework markers. Record the detected framework (SPRING_BOOT, QUARKUS, or MICRONAUT) and the signal that identified it.
If no supported framework is detected:
"No supported framework detected. This skill requires Spring Boot (3.1+), Quarkus (3.0+), or Micronaut (4.0+). For non-framework Java code, try /generate-unit-tests instead."
Then stop.
If multiple frameworks are detected:
"Multiple frameworks detected: {framework1} and {framework2}. Please confirm which framework this project uses."
Then stop and wait for user response.
Step 4: Detect JUnit Version
Check existing test files and build configuration for JUnit version signals:
- Scan test files in
src/test/java for import patterns:
org.junit.jupiter → JUnit 5
org.junit.Test (without jupiter) → JUnit 4
- Check build files for dependency declarations:
junit-jupiter or junit-bom 5.x → JUnit 5
junit:junit:4.x → JUnit 4
If JUnit 5 is detected or no signal is found (default): Proceed.
If JUnit 4 is detected:
"Integration test generation requires JUnit 5 (all supported frameworks — Spring Boot, Quarkus, and Micronaut — use JUnit 5 test extensions). Please add the JUnit 5 dependency to your project and try again."
Then stop.
Step 5: Check Testcontainers Dependency and Version
Scan the build files for Testcontainers dependencies:
- Maven:
org.testcontainers groupId
- Gradle:
org.testcontainers in any dependency
If Testcontainers is not found, inform the user with exact coordinates for their build tool. Read reference/database-detection.md for the dependency coordinates and version requirements. Note that H2 in-memory tests do not require Testcontainers.
If Testcontainers is found, check the version:
- Look for a
<testcontainers.version> property (Maven) or ext['testcontainers.version'] (Gradle)
- Look for a
testcontainers-bom version in <dependencyManagement> (Maven) or platform(...) (Gradle)
- If the version is explicitly set and is < 1.21.0, inform the user:
"Your Testcontainers version ({version}) may be incompatible with modern Docker runtimes (API v1.40+ required). Upgrade to 1.21.0+ by setting <testcontainers.version>1.21.0</testcontainers.version> in your build file."
- If the version is managed by a framework BOM (Spring Boot, Quarkus, Micronaut) and cannot be extracted, proceed — but include this comment at the top of the generated test file:
Step 6: Detect Class Type
Analyze the target class to determine its type:
| Class Type | Detection Signals |
|---|
| REPOSITORY | Extends JpaRepository, CrudRepository, PagingAndSortingRepository (Spring Data), PanacheRepository, PanacheEntityBase (Quarkus Panache), CrudRepository, PageableRepository (Micronaut Data); or annotated with @Repository |
| CONTROLLER | Annotated with @RestController or @Controller (Spring), @Path (Quarkus JAX-RS), @Controller (Micronaut) |
| SERVICE | Annotated with @Service, @Component (Spring), @ApplicationScoped, @Singleton, @RequestScoped (Quarkus CDI), @Singleton, @Prototype (Micronaut); AND has at least one dependency on an external system (database, message broker, cache, HTTP API) |
If none of the above signals match:
"No integration points found in {ClassName} (no database access, HTTP endpoints, or external service calls). Try /generate-unit-tests for unit test coverage instead."
Then stop.
Step 7: Detect Integration Points
Scan the class's constructor parameters and injected fields for external system dependencies:
Database: Any repository-type dependency (see REPOSITORY signals above)
Message Brokers:
- Spring:
KafkaTemplate, RabbitTemplate, JmsTemplate
- Quarkus:
@Channel, @Outgoing, @Incoming (SmallRye Reactive Messaging), @ConnectorAttribute
- Micronaut:
@KafkaClient, @KafkaListener, @RabbitClient, @RabbitListener
Cache:
- Spring:
RedisTemplate, StringRedisTemplate, CacheManager
- Quarkus:
RedisDataSource, ReactiveRedisDataSource
- Micronaut:
RedisCommands, StatefulRedisConnection
HTTP Clients:
- Spring:
RestTemplate, WebClient, RestClient
- Quarkus:
@RestClient annotated interfaces
- Micronaut:
@Client annotated interfaces or injected HttpClient
Record each integration point with its type and the Testcontainers module (or WireMock) needed.
Step 8: Detect Database Type
Read reference/database-detection.md now for the complete detection matrix and procedure.
Follow the detection priority order (driver dependency → datasource URL → JPA dialect). Default to H2 in-memory if no database type can be determined.
Step 9: Resolve Test File Path
Determine the test file location using the .integration subpackage convention:
- Take the source file path (e.g.,
src/main/java/com/example/repository/OrderRepository.java)
- Mirror it under
src/test/java with an .integration subpackage:
src/test/java/com/example/repository/integration/OrderRepositoryTest.java
- The test class name is
<ClassName>Test
Check if the test file already exists. If it does, proceed to Step 13 (Supplementation) instead of generating a new file.
Step 10: Generate Repository Tests
This step applies only when classType is REPOSITORY.
Read the framework-specific patterns reference file for the detected framework:
Also read examples/spring-boot-repository.md for a complete input/output example.
Extract repository methods:
- Custom query methods: Methods with
@Query annotations (Spring/Micronaut), @NamedQuery (Quarkus), or derived query methods (e.g., findByStatus, countByCustomerName)
- Inherited CRUD methods: From the framework base interface (save, findById, findAll, delete, count, etc.)
- Entity type: Extract from the generic type parameter (e.g.,
JpaRepository<Order, Long> → entity is Order, ID is Long)
Read the entity class to understand its fields, relationships, and constraints. This informs test data creation.
Generate the test class with:
- Class-level annotations: Framework-appropriate test bootstrap (see reference files)
- Container setup: Testcontainers database container with
@ServiceConnection (Spring) or DevServices (Quarkus) or Test Resources (Micronaut). For H2 default: test property source instead.
- Repository injection:
@Autowired (Spring), @Inject (Quarkus/Micronaut)
- Setup method:
@BeforeEach to clean data between tests (for Spring/Micronaut), or @TestTransaction per test (for Quarkus)
- Test methods: For Spring Boot and Micronaut, group in
@Nested inner classes by method name (PascalCase). For Quarkus, do NOT use @Nested classes — Quarkus CDI rejects interceptor bindings (@TestTransaction) on inner class methods. Instead, use flat test methods with descriptive names.
- CRUD operations: save, findById (found + not found), findAll, delete
- Custom queries: One happy-path test per custom method with realistic test data that exercises the query logic
- Edge cases: Empty results, null parameters (where applicable)
- Test naming:
shouldBehaviorWhenCondition camelCase
- Assertions: AssertJ (
assertThat(...))
- Test data: Realistic, domain-appropriate values (not nulls, zeros, or "test" strings)
Write the generated test file to the resolved path.
Step 11: Generate Controller Tests
This step applies only when classType is CONTROLLER.
Read the framework-specific patterns reference file for the detected framework (same files as Step 10).
Extract endpoint mappings:
- For each public method in the controller, extract:
- HTTP method (
GET, POST, PUT, DELETE, PATCH)
- Path (from
@RequestMapping/@GetMapping/etc. in Spring, @Path/@GET/etc. in Quarkus, @Get/@Post/etc. in Micronaut)
- Path variables and query parameters
- Request body type and validation annotations (
@Valid, @NotNull, @Size, etc.)
- Response type and status code
Generate the test class with:
- Class-level annotations: Full-stack test bootstrap with database container (same as repository tests). For Spring: add
@AutoConfigureMockMvc.
- HTTP client setup:
- Spring:
@Autowired MockMvc mockMvc
- Quarkus: RestAssured static imports (
given().when().then())
- Micronaut:
@Inject @Client("/") HttpClient client
- Data setup: Inject the backing repository and insert test data in
@BeforeEach
- Test methods: For Spring Boot and Micronaut, group in
@Nested inner classes by endpoint. For Quarkus, use flat test methods (no @Nested — same CDI limitation as repository tests).
- GET endpoints: Test with existing data (assert status + body), test with no data (empty list or 404), test with invalid ID (404)
- POST endpoints: Test with valid body (assert 201 + response body), test with invalid body (assert 400 + validation errors)
- PUT/PATCH endpoints: Test update with valid data, test update of non-existent resource (404)
- DELETE endpoints: Test successful deletion, test deletion of non-existent resource
- Validation tests: For endpoints with
@Valid request bodies, generate tests that violate each validation constraint
Write the generated test file to the resolved path.
Step 12: Generate Service Tests
This step applies only when classType is SERVICE.
Read the framework-specific patterns reference file for the detected framework.
For each integration point detected in Step 7, set up the appropriate test infrastructure:
| Integration Point | Testcontainers Module | Setup Pattern |
|---|
| Database (via repository) | Per database-detection.md | Same as repository tests |
| Kafka | org.testcontainers:kafka | KafkaContainer (Spring @ServiceConnection), DevServices (Quarkus), Test Resources (Micronaut) |
| Redis | org.testcontainers:redis (or GenericContainer) | Redis container with exposed port 6379 |
| RabbitMQ | org.testcontainers:rabbitmq | RabbitMQContainer |
| HTTP API (external) | None | WireMock (WireMockExtension) with stub setup |
Generate the test class with:
- Container setup: One container per unique external dependency
- Service injection: Direct injection of the service under test
- Test methods per integration point:
- Message publishing: Send a message through the service, consume from the topic/queue to verify
- Cache operations: Put/get values through the service, verify cache state
- HTTP client calls: Set up WireMock stubs, call the service method, verify WireMock received the expected request
- Error scenarios: Test behavior when external service is unavailable or returns errors (WireMock returning 500, timeout simulation)
Write the generated test file to the resolved path.
Step 13: Supplement Existing Test File
This step only applies when a test file already exists at the resolved path (from Step 9).
- Read both the source class and the existing test file.
- Extract all public method names (or endpoint mappings) from the source class.
- For each public method, check if it is already covered in the existing test file using these signals:
- High confidence: Method name appears in a
@Nested class name (e.g., class FindByStatus covers findByStatus)
- High confidence: Method is called on the test subject instance inside a
@Test method
- Medium confidence: Method name is a substring of a test method name
- For methods that are NOT covered:
- Generate new
@Nested classes with test methods following all the rules above
- Append them at the end of the test class (before the closing brace)
- Add any new imports needed
- Never modify, reorder, or duplicate existing test methods.
- If all methods are already covered:
"All public methods in {ClassName} already have integration test coverage in {TestClassName}."
Make no changes.
Additional Resources
Now generate the integration test class for the file at: $ARGUMENTS