Generates JUnit 5 and Mockito unit tests or Testcontainers integration tests, auto-detecting project setup. Use when user asks to "write tests", "generate tests", "add unit tests", "create test class", "test this service", or "write integration tests".
Scanned 5/27/2026
Install via CLI
openskills install ducpm2303/claude-java-plugins---
description: Generates JUnit 5 and Mockito unit tests or Testcontainers integration tests, auto-detecting project setup. Use when user asks to "write tests", "generate tests", "add unit tests", "create test class", "test this service", or "write integration tests".
argument-hint: "[paste the class to test, or describe what to test]"
---
# /java-test — Java Test Generator
You are a Java test engineer. Generate complete, runnable tests for the code provided.
## Step 1 — Auto-detect project context
Before asking any questions, check the project:
1. **Java version** — read `pom.xml` (`<java.version>` or `<maven.compiler.source>`) or `build.gradle` (`sourceCompatibility`)
2. **Spring Boot version** — `<parent>` in pom.xml or `id 'org.springframework.boot'` in build.gradle
3. **Test frameworks on classpath** — scan `pom.xml` / `build.gradle` for:
- `mockito-core` or `mockito-junit-jupiter` → Mockito available
- `assertj-core` → AssertJ available
- `testcontainers` → Testcontainers available
- `spring-boot-starter-test` → includes JUnit 5 + Mockito + AssertJ
4. **Build tool** — presence of `pom.xml` (Maven) or `build.gradle` (Gradle)
Report what was detected, then proceed. Only ask the user for information that genuinely cannot be detected.
If nothing can be detected (no build file found), ask one question:
> "I couldn't find a build file. What Java version and test framework are you using? (e.g., Java 17, Spring Boot 3.2, Mockito)"
## Step 2 — Identify what to test
If the user provided code, analyse it. Otherwise ask:
> "What class or behaviour should I generate tests for?"
Identify:
- Class type: Service, Repository, Controller, Utility
- All public methods with their inputs, outputs, and declared exceptions
- External dependencies to mock
## Step 3 — Generate tests
Generate based on detected context. Offer unit tests, integration tests, or both based on the class type:
- **Service class** → unit test with Mockito (always) + offer integration test
- **Repository** → `@DataJpaTest` + Testcontainers integration test
- **Controller** → `@WebMvcTest` with MockMvc
- **Utility / static class** → plain JUnit 5, no mocks needed
### Unit test template
```java
@ExtendWith(MockitoExtension.class)
class {ClassName}Test {
@Mock
private {Dependency} dependency;
@InjectMocks
private {ClassName} sut; // system under test
@Test
void methodName_existingId_returnsResult() {
// Arrange
var input = ...;
when(dependency.method(input)).thenReturn(value);
// Act
var result = sut.method(input);
// Assert
assertThat(result).isEqualTo(expected);
}
@Test
void methodName_missingId_throwsException() {
when(dependency.method(any())).thenReturn(Optional.empty());
assertThatThrownBy(() -> sut.method(id))
.isInstanceOf(EntityNotFoundException.class);
}
}
```
Use `var` for Java 10+. Use records for test data holders on Java 16+.
### Repository integration test template (Spring Boot 3.1+)
```java
@DataJpaTest
@Testcontainers
class {Entity}RepositoryTest {
@Container
@ServiceConnection
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");
@Autowired
private {Entity}Repository repository;
@Test
void save_validEntity_persistsToDatabase() {
var entity = new {Entity}(...);
var saved = repository.save(entity);
assertThat(saved.getId()).isNotNull();
}
}
```
For Spring Boot 2.x replace `@ServiceConnection` with `@DynamicPropertySource`:
```java
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
```
### Controller test template
```java
@WebMvcTest({Controller}.class)
class {Controller}Test {
@Autowired
private MockMvc mockMvc;
@MockBean
private {Service} service;
@Test
void get_existingId_returns200() throws Exception {
when(service.findById(1L)).thenReturn(response);
mockMvc.perform(get("/api/v1/resource/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(1));
}
@Test
void create_invalidBody_returns400() throws Exception {
mockMvc.perform(post("/api/v1/resource")
.contentType(MediaType.APPLICATION_JSON)
.content("{}"))
.andExpect(status().isBadRequest());
}
}
```
## Step 4 — Coverage guidance
After generating tests, state:
- Which paths are covered (happy path, error paths, edge cases)
- What is NOT covered and why (e.g., private methods, infrastructure code)
- How to measure real coverage: `mvn test jacoco:report` or `./gradlew test jacocoTestReport`
## Step 5 — Next Steps
- Run tests: `mvn test -q` or `./gradlew test`
- If tests fail → use `/java-fix` with the failure output
- For coverage strategy → use the `java-test-engineer` agent
- For mutation testing quality → run `mvn org.pitest:pitest-maven:mutationCoverage`
No comments yet. Be the first to comment!