---
name: business-test-gen
description: SpecPow business-test-gen skill
---

# 测试代码生成

> 根据业务层代码，生成单元测试

## 技术栈配置

本技能的**默认**技术栈为 JUnit5 + Mockito（Java），但会根据项目实际使用的测试框架自动适配：

- **测试框架** — 优先使用项目已有的框架（JUnit5 / JUnit4 / TestNG / Jest / Vitest / pytest）
- **Mock 工具** — 匹配项目已有 Mock 方案（Mockito / Sinon / unittest.mock / gomock）
- **断言库** — 使用项目已有的断言风格（AssertJ / Hamcrest / Jest expect / chai）
- **运行命令** — 从项目 package.json / pom.xml / build.gradle 推断测试运行命令

## 触发条件

- 用户要求生成测试代码
- 执行 apply-change 中任务包含验证步骤
- 用户提到"写测试"/"单测"/"覆盖率"

## 铁律

1. **测行为不测实现** — 测试输入→输出，不关心内部怎么实现
2. **Mock 外部依赖** — 数据库、RPC、HTTP 全部 Mock
3. **边界必测** — null、空集合、极值、异常路径
4. **失败自修** — 测试失败自动修复，最多 3 轮

## 工作流

### 阶段 1：分析被测代码
1. 读取目标 Service/Mapper 类
2. 识别所有 public 方法
3. 分析方法依赖（需要 Mock 的对象）
4. 提取业务规则和边界条件

### 阶段 2：生成测试

**测试类结构：**
```java
@ExtendWith(MockitoExtension.class)
class XxxServiceTest {

    @InjectMocks
    private XxxServiceImpl xxxService;

    @Mock
    private XxxMapper xxxMapper;

    // 每个方法至少 2 个测试：正常路径 + 异常路径
    @Test
    @DisplayName("方法名 - 场景描述")
    void methodName_scenario() {
        // Given
        // When
        // Then
    }
}
```

**覆盖场景类型：**
- 正常输入 → 预期输出
- null 参数 → 抛出异常或返回默认值
- 空集合 → 正确处理
- 数据库无记录 → 返回 null
- 业务规则违反 → 抛出 BusinessException

### 阶段 3：执行与自修

1. 运行测试：`mvn test -Dtest=XxxServiceTest`
2. 如果失败，分析错误原因
3. 修复测试代码（不修改被测代码）
4. 最多 3 轮，仍失败则报告问题

## 红旗

- 被测类不存在 → 先生成业务代码
- 项目无测试框架 → 询问用户选择测试框架
- 覆盖率低于 60% → 补充测试用例
