---
description: 测试规范（RuoYi Cloud 后端 + Vue2 前端）
globs: ["**/*Test.java", "**/*Tests.java"]
alwaysApply: false
---

# 测试规范（RuoYi Cloud）

## 后端单元测试

### 测试类命名与位置

- 命名：`{Entity}ServiceImplTest`
- 位置：`src/test/java/`，与被测类同包路径

### 标准模板

```java
@SpringBootTest
@Transactional
@Rollback
class JzObjectServiceImplTest
{
    @Autowired
    private IJzObjectService jzObjectService;

    @Test
    @DisplayName("新增社区矫正对象 - 正常流程")
    void testInsert_success()
    {
        JzObject obj = new JzObject();
        obj.setXM("测试姓名");
        int rows = jzObjectService.insertJzObject(obj);
        assertTrue(rows > 0);
    }

    @Test
    @DisplayName("删除不存在记录 - 应抛出 ServiceException")
    void testDelete_notExists()
    {
        ServiceException ex = assertThrows(ServiceException.class,
            () -> jzObjectService.deleteJzObjectBySQJZDXBH("not-exist-id"));
        assertNotNull(ex.getMessage());
    }
}
```

### 关键约束

- ✅ `@DisplayName` 中文描述
- ✅ `@Transactional + @Rollback` 防止污染数据库
- ✅ 业务异常用 `assertThrows(ServiceException.class, ...)`
- ✅ 注入用 `@Autowired`（与项目一致）
- ❌ 禁止测试间执行顺序依赖
- ❌ 禁止 `Thread.sleep()` 处理异步

## 前端测试（可选）

本项目前端以手动测试为主。若需自动化：

- 工具：Jest + Vue Test Utils（Vue2 兼容版）
- 接口调用必须 mock，禁止真实请求
- 参考 `ruoyi-ui` 现有页面结构编写

## 接口联调 Checklist

- [ ] GET `/list` 返回 TableDataInfo（rows + total）
- [ ] GET `/{id}` 返回 AjaxResult
- [ ] POST/PUT 返回 toAjax 结果
- [ ] 无权限时返回 403
- [ ] 业务校验失败返回 ServiceException 消息
- [ ] 导出接口返回 Excel 文件流

## 测试覆盖率建议

| 层级 | 重点 |
|------|------|
| ServiceImpl | 业务校验、异常分支、事务 |
| Controller | 权限注解、参数绑定 |
| Mapper XML | 复杂动态 SQL（集成测试） |
