Token导航 LogoToken导航TokenDH.com
研究检索只读github未标认证来源可访问许可证需确认审计通过

java-test-generatorJava 测试生成器

Agent Skill

用于辅助 Java 项目开发、面向对象设计、Spring 生态、Maven 或 Gradle 依赖和后端工程实践。它适合让 Agent 分析类结构、设计接口、整理服务分层、生成测试或检查常见代码坏味道。使用时需要结合项目已有架构、包结构和依赖版本,不应只按通用教程改代码;涉及数据库、事务、并发或框架配置时,应先确认运行环境和回归测试范围。

总安装

367

周安装

15

GitHub Stars

1

下载量

118
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:java-test-generator(Java 测试生成器)
来源仓库:https://github.com/dawiddutoit/custom-claude
仓库路径:skills/java-test-generator
安装命令:
npx skills add https://github.com/dawiddutoit/custom-claude --skill java-test-generator
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/dawiddutoit/custom-claude --skill java-test-generator

简介

用于辅助 Java 项目开发,支持类结构分析、接口设计和测试用例生成。

  • 适合处理 Spring 生态集成、Maven/Gradle 依赖管理及后端工程实践。
  • 使用时需结合项目架构和依赖版本,避免直接套用通用模板修改代码。
  • 涉及数据库或并发场景时,应先确认运行环境并规划回归测试范围。
  • 安装方式:通过 GitHub 仓库添加,需核对来源站点与权限设置。

SKILL.md

Java Test Generator

Table of Contents

Purpose

Generates comprehensive, well-structured JUnit 5 test cases for Java code with proper mocking using Mockito, edge case coverage, parameterized tests, and adherence to testing best practices.

When to Use

Use this skill when you need to:

  • Generate JUnit 5 test cases for Java classes
  • Create unit tests with Mockito mocking
  • Write parameterized tests for multiple input scenarios
  • Add test coverage for new or existing code
  • Test service layers with dependency mocking
  • Generate tests following Arrange-Act-Assert pattern
  • Create tests for edge cases and boundary conditions
  • Test exception handling scenarios
  • Verify mock interactions with Mockito
  • Generate tests for Spring Boot components
  • Achieve high test coverage (>80%)
  • Bootstrap test suites for new features

Quick Start

Generate tests for any Java class instantly:

# Generate tests for a service class
Generate tests for UserService.java

# Generate tests for multiple classes
Generate tests for all classes in src/main/java/com/example/service/

Instructions

Step 1: Analyze Source Code

Read the target Java class and understand:

  • Class purpose and responsibilities
  • Public methods that need testing
  • Dependencies (fields, constructor parameters)
  • Return types and exception handling
  • Business logic and edge cases
  • Validation logic

Use Grep to find related classes if context is needed:

grep "class UserService" src/main/java/**/*.java

Step 2: Identify Test Scenarios

For each public method, identify:

Happy Path Tests:

  • Valid inputs producing expected outputs
  • Typical use cases

Edge Cases:

  • Boundary values (min, max, zero, empty)
  • Null inputs (if not using @NonNull)
  • Empty collections
  • Special characters in strings

Error Cases:

  • Invalid inputs
  • Constraint violations
  • Exception scenarios

State-Based Tests:

  • Different object states
  • Conditional branch coverage

Integration Points:

  • Dependency interactions
  • Method call verification

Step 3: Generate Test Class Structure

Create test class following conventions:

Naming: [ClassName]Test.java (e.g., UserServiceTest.java) Location: Mirror source structure in src/test/java/

Structure Template:

@ExtendWith(MockitoExtension.class)
class ClassNameTest {
    // Mocks for dependencies
    @Mock
    private DependencyClass mockDependency;

    // System under test
    @InjectMocks
    private ClassUnderTest classUnderTest;

    // Test data builders
    private TestDataBuilder testDataBuilder;

    @BeforeEach
    void setUp() {
        // Common test setup
    }

    @Nested
    @DisplayName("methodName() tests")
    class MethodNameTests {
        // Group related tests
    }
}

Step 4: Write Individual Test Methods

Follow the Arrange-Act-Assert (AAA) pattern:

@Test
@DisplayName("should return user when valid ID provided")
void shouldReturnUser_WhenValidIdProvided() {
    // Arrange
    String userId = "123";
    User expectedUser = new User(userId, "John Doe");
    when(mockRepository.findById(userId)).thenReturn(Optional.of(expectedUser));

    // Act
    Optional<User> result = userService.getUser(userId);

    // Assert
    assertThat(result).isPresent();
    assertThat(result.get()).isEqualTo(expectedUser);
    verify(mockRepository).findById(userId);
}

Test Method Naming Conventions:

  • shouldDoSomething_WhenCondition() format
  • Or should_DoSomething_When_Condition() for readability
  • Descriptive names that explain the scenario

Step 5: Add Parameterized Tests for Multiple Inputs

Use @ParameterizedTest for testing multiple similar scenarios:

@ParameterizedTest
@ValueSource(strings = {"", "  ", "\t", "\n"})
@DisplayName("should throw exception for blank names")
void shouldThrowException_ForBlankNames(String invalidName) {
    assertThrows(IllegalArgumentException.class,
        () -> userService.createUser(invalidName));
}

@ParameterizedTest
@CsvSource({
    "john@example.com, true",
    "invalid-email, false",
    "@example.com, false",
    "john@, false"
})
@DisplayName("should validate email correctly")
void shouldValidateEmail_Correctly(String email, boolean expected) {
    boolean result = validator.isValidEmail(email);
    assertThat(result).isEqualTo(expected);
}

Step 6: Add Exception Testing

Test exception scenarios explicitly:

@Test
@DisplayName("should throw UserNotFoundException when user not found")
void shouldThrowUserNotFoundException_WhenUserNotFound() {
    // Arrange
    String userId = "999";
    when(mockRepository.findById(userId)).thenReturn(Optional.empty());

    // Act & Assert
    assertThrows(UserNotFoundException.class,
        () -> userService.getUser(userId));
    verify(mockRepository).findById(userId);
}

Step 7: Add Verification for Mock Interactions

Verify dependencies are called correctly:

@Test
@DisplayName("should save user to repository")
void shouldSaveUser_ToRepository() {
    // Arrange
    User newUser = new User("John Doe", "john@example.com");

    // Act
    userService.createUser(newUser);

    // Assert
    verify(mockRepository).save(newUser);
    verifyNoMoreInteractions(mockRepository);
}

Step 8: Generate Test Data Builders (Optional)

For complex objects, create builder methods:

private User createTestUser(String id, String name) {
    return User.builder()
        .id(id)
        .name(name)
        .email(name.toLowerCase() + "@example.com")
        .createdAt(LocalDateTime.now())
        .build();
}

Step 9: Add Coverage for Edge Cases

Include boundary and special cases:

@Nested
@DisplayName("Edge case tests")
class EdgeCaseTests {
    @Test
    @DisplayName("should handle empty list")
    void shouldHandleEmptyList() {
        List<User> emptyList = Collections.emptyList();
        List<String> result = userService.extractNames(emptyList);
        assertThat(result).isEmpty();
    }

    @Test
    @DisplayName("should handle null optional")
    void shouldHandleNullOptional() {
        when(mockRepository.findById(anyString())).thenReturn(Optional.empty());
        Optional<User> result = userService.getUser("123");
        assertThat(result).isEmpty();
    }
}

Examples

Example 1: Generate Tests for Simple Service

Source Code:

@Service
@RequiredArgsConstructor
public class UserService {
    private final UserRepository userRepository;

    public Optional<User> getUser(String id) {
        return userRepository.findById(id);
    }

    public User createUser(String name, String email) {
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("Name cannot be blank");
        }
        User user = new User(name, email);
        return userRepository.save(user);
    }
}

Generated Test:

@ExtendWith(MockitoExtension.class)
@DisplayName("UserService Tests")
class UserServiceTest {

    @Mock
    private UserRepository mockRepository;

    @InjectMocks
    private UserService userService;

    @Nested
    @DisplayName("getUser() tests")
    class GetUserTests {

        @Test
        @DisplayName("should return user when ID exists")
        void shouldReturnUser_WhenIdExists() {
            // Arrange
            String userId = "123";
            User expectedUser = new User("John Doe", "john@example.com");
            when(mockRepository.findById(userId))
                .thenReturn(Optional.of(expectedUser));

            // Act
            Optional<User> result = userService.getUser(userId);

            // Assert
            assertThat(result).isPresent();
            assertThat(result.get()).isEqualTo(expectedUser);
            verify(mockRepository).findById(userId);
        }

        @Test
        @DisplayName("should return empty when ID not found")
        void shouldReturnEmpty_WhenIdNotFound() {
            // Arrange
            String userId = "999";
            when(mockRepository.findById(userId))
                .thenReturn(Optional.empty());

            // Act
            Optional<User> result = userService.getUser(userId);

            // Assert
            assertThat(result).isEmpty();
            verify(mockRepository).findById(userId);
        }

        @Test
        @DisplayName("should handle null ID")
        void shouldHandleNullId() {
            // Act
            Optional<User> result = userService.getUser(null);

            // Assert
            assertThat(result).isEmpty();
            verify(mockRepository).findById(null);
        }
    }

    @Nested
    @DisplayName("createUser() tests")
    class CreateUserTests {

        @Test
        @DisplayName("should create user with valid inputs")
        void shouldCreateUser_WithValidInputs() {
            // Arrange
            String name = "John Doe";
            String email = "john@example.com";
            User userToSave = new User(name, email);
            User savedUser = new User(name, email);
            savedUser.setId("123");
            when(mockRepository.save(any(User.class)))
                .thenReturn(savedUser);

            // Act
            User result = userService.createUser(name, email);

            // Assert
            assertThat(result).isNotNull();
            assertThat(result.getId()).isEqualTo("123");
            verify(mockRepository).save(any(User.class));
        }

        @ParameterizedTest
        @NullAndEmptySource
        @ValueSource(strings = {"  ", "\t", "\n"})
        @DisplayName("should throw exception for invalid names")
        void shouldThrowException_ForInvalidNames(String invalidName) {
            // Act & Assert
            assertThrows(IllegalArgumentException.class,
                () -> userService.createUser(invalidName, "john@example.com"));
            verifyNoInteractions(mockRepository);
        }

        @Test
        @DisplayName("should accept null email")
        void shouldAcceptNullEmail() {
            // Arrange
            String name = "John Doe";
            User savedUser = new User(name, null);
            when(mockRepository.save(any(User.class)))
                .thenReturn(savedUser);

            // Act
            User result = userService.createUser(name, null);

            // Assert
            assertThat(result).isNotNull();
            verify(mockRepository).save(any(User.class));
        }
    }
}

Example 2: Generate Tests with Complex Mocking

Source Code:

@Service
@RequiredArgsConstructor
public class OrderService {
    private final OrderRepository orderRepository;
    private final PaymentService paymentService;
    private final NotificationService notificationService;

    public Order processOrder(OrderRequest request) {
        Order order = createOrder(request);
        Payment payment = paymentService.processPayment(
            order.getTotalAmount()
        );
        if (payment.isSuccessful()) {
            order.setStatus(OrderStatus.CONFIRMED);
            Order savedOrder = orderRepository.save(order);
            notificationService.sendOrderConfirmation(savedOrder);
            return savedOrder;
        } else {
            throw new PaymentFailedException("Payment failed");
        }
    }
}

Generated Test:

@ExtendWith(MockitoExtension.class)
@DisplayName("OrderService Tests")
class OrderServiceTest {

    @Mock
    private OrderRepository mockOrderRepository;

    @Mock
    private PaymentService mockPaymentService;

    @Mock
    private NotificationService mockNotificationService;

    @InjectMocks
    private OrderService orderService;

    @Captor
    private ArgumentCaptor<Order> orderCaptor;

    private OrderRequest testRequest;

    @BeforeEach
    void setUp() {
        testRequest = OrderRequest.builder()
            .customerId("CUST-123")
            .items(List.of(new OrderItem("ITEM-1", 2, 10.00)))
            .build();
    }

    @Nested
    @DisplayName("processOrder() tests")
    class ProcessOrderTests {

        @Test
        @DisplayName("should process order successfully with successful payment")
        void shouldProcessOrder_WithSuccessfulPayment() {
            // Arrange
            Payment successfulPayment = new Payment("PAY-123", true);
            when(mockPaymentService.processPayment(anyDouble()))
                .thenReturn(successfulPayment);
            Order savedOrder = new Order();
            savedOrder.setId("ORD-123");
            savedOrder.setStatus(OrderStatus.CONFIRMED);
            when(mockOrderRepository.save(any(Order.class)))
                .thenReturn(savedOrder);

            // Act
            Order result = orderService.processOrder(testRequest);

            // Assert
            assertThat(result).isNotNull();
            assertThat(result.getId()).isEqualTo("ORD-123");
            assertThat(result.getStatus()).isEqualTo(OrderStatus.CONFIRMED);

            // Verify interactions in correct order
            InOrder inOrder = inOrder(
                mockPaymentService,
                mockOrderRepository,
                mockNotificationService
            );
            inOrder.verify(mockPaymentService).processPayment(20.00);
            inOrder.verify(mockOrderRepository).save(orderCaptor.capture());
            inOrder.verify(mockNotificationService)
                .sendOrderConfirmation(savedOrder);

            // Verify captured order state
            Order capturedOrder = orderCaptor.getValue();
            assertThat(capturedOrder.getStatus())
                .isEqualTo(OrderStatus.CONFIRMED);
        }

        @Test
        @DisplayName("should throw exception when payment fails")
        void shouldThrowException_WhenPaymentFails() {
            // Arrange
            Payment failedPayment = new Payment("PAY-456", false);
            when(mockPaymentService.processPayment(anyDouble()))
                .thenReturn(failedPayment);

            // Act & Assert
            assertThrows(PaymentFailedException.class,
                () -> orderService.processOrder(testRequest));

            // Verify
            verify(mockPaymentService).processPayment(20.00);
            verifyNoInteractions(mockOrderRepository);
            verifyNoInteractions(mockNotificationService);
        }

        @Test
        @DisplayName("should handle payment service exception")
        void shouldHandlePaymentServiceException() {
            // Arrange
            when(mockPaymentService.processPayment(anyDouble()))
                .thenThrow(new RuntimeException("Service unavailable"));

            // Act & Assert
            assertThrows(RuntimeException.class,
                () -> orderService.processOrder(testRequest));

            // Verify
            verifyNoInteractions(mockOrderRepository);
            verifyNoInteractions(mockNotificationService);
        }
    }
}

Example 3: Generate Parameterized Tests for Validation

Source Code:

public class EmailValidator {
    public boolean isValid(String email) {
        if (email == null || email.isBlank()) {
            return false;
        }
        return email.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$");
    }
}

Generated Test:

@DisplayName("EmailValidator Tests")
class EmailValidatorTest {

    private EmailValidator validator;

    @BeforeEach
    void setUp() {
        validator = new EmailValidator();
    }

    @Nested
    @DisplayName("Valid email tests")
    class ValidEmailTests {

        @ParameterizedTest
        @ValueSource(strings = {
            "user@example.com",
            "john.doe@example.com",
            "user+tag@example.co.uk",
            "123@example.com",
            "user_name@example.com"
        })
        @DisplayName("should return true for valid emails")
        void shouldReturnTrue_ForValidEmails(String email) {
            assertThat(validator.isValid(email)).isTrue();
        }
    }

    @Nested
    @DisplayName("Invalid email tests")
    class InvalidEmailTests {

        @ParameterizedTest
        @NullAndEmptySource
        @ValueSource(strings = {
            "  ",
            "\t",
            "invalid",
            "@example.com",
            "user@",
            "user@.com",
            "user @example.com",
            "user@example",
            "user@@example.com"
        })
        @DisplayName("should return false for invalid emails")
        void shouldReturnFalse_ForInvalidEmails(String email) {
            assertThat(validator.isValid(email)).isFalse();
        }
    }

    @Nested
    @DisplayName("Edge case tests")
    class EdgeCaseTests {

        @Test
        @DisplayName("should handle very long email")
        void shouldHandleVeryLongEmail() {
            String longEmail = "a".repeat(100) + "@example.com";
            boolean result = validator.isValid(longEmail);
            assertThat(result).isTrue();
        }

        @ParameterizedTest
        @CsvSource({
            "user@example.com, true",
            "USER@EXAMPLE.COM, true",
            "User@Example.Com, true"
        })
        @DisplayName("should handle different cases")
        void shouldHandleDifferentCases(String email, boolean expected) {
            assertThat(validator.isValid(email)).isEqualTo(expected);
        }
    }
}

Requirements

Dependencies

Add to pom.xml or build.gradle:

Maven:

<dependencies>
    <!-- JUnit 5 -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.10.0</version>
        <scope>test</scope>
    </dependency>

    <!-- Mockito -->
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>5.5.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-junit-jupiter</artifactId>
        <version>5.5.0</version>
        <scope>test</scope>
    </dependency>

    <!-- AssertJ (recommended) -->
    <dependency>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-core</artifactId>
        <version>3.24.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Gradle:

testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
testImplementation 'org.mockito:mockito-core:5.5.0'
testImplementation 'org.mockito:mockito-junit-jupiter:5.5.0'
testImplementation 'org.assertj:assertj-core:3.24.2'

Import Statements

Generated tests include:

import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.*;
import org.mockito.*;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;

Testing Best Practices

Naming:

  • Test class: [ClassName]Test
  • Test method: should[ExpectedBehavior]_When[Condition]
  • Use @DisplayName for readable test names

Structure:

  • Follow Arrange-Act-Assert pattern
  • Use @Nested classes to group related tests
  • One assertion concept per test method

Mocking:

  • Mock external dependencies only
  • Use @InjectMocks for class under test
  • Verify interactions when behavior matters
  • Use ArgumentCaptor for complex verifications

Coverage:

  • Test happy paths first
  • Add edge cases and boundary conditions
  • Test exception scenarios explicitly
  • Aim for high branch coverage, not just line coverage

Maintainability:

  • Keep tests simple and focused
  • Use test data builders for complex objects
  • Extract common setup to @BeforeEach
  • Avoid test interdependence

Output Format

When generating tests, provide:

  1. File location for the test class
  2. Complete test class with all imports
  3. Explanation of test scenarios covered
  4. Coverage report showing what's tested
  5. Run command to execute tests

Example output structure:

## Generated Test: UserServiceTest

**Location:** src/test/java/com/example/service/UserServiceTest.java

**Test Coverage:**
- getUser() - 3 test cases (happy path, not found, null ID)
- createUser() - 4 test cases (valid input, blank name, null email, special chars)

**Edge Cases Covered:**
- Empty/null/blank strings
- Null optional handling
- Exception scenarios

**Run Tests:**

mvn test -Dtest=UserServiceTest

or

gradle test --tests UserServiceTest

Error Handling

If test generation cannot be completed:

  1. Source file not found: Use Glob to search for the file
  2. Missing dependencies: Identify which fields need mocking
  3. Complex business logic: Ask for clarification on expected behavior
  4. Unable to determine test scenarios: Request example use cases

Always fail-fast with clear error messages rather than generating incomplete tests.

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

36.68%
按下载量换算43

Claude

31.1%
按下载量换算37

Cursor

16.77%
按下载量换算20

Gemini CLI

9.37%
按下载量换算11

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

只读

该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills