|
|
@@ -0,0 +1,171 @@
|
|
|
+# cfc-backend 测试报告
|
|
|
+
|
|
|
+**测试日期:** 2026-06-27
|
|
|
+**测试范围:** cfc-backend 全部 40 个测试类
|
|
|
+**测试工具:** Maven Surefire (JUnit 5 + Mockito)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 一、执行摘要
|
|
|
+
|
|
|
+| 指标 | 数值 |
|
|
|
+|------|------|
|
|
|
+| 总测试数 | 513 |
|
|
|
+| 通过 | 46 |
|
|
|
+| 失败/错误 | 467 |
|
|
|
+| 跳过 | 0 |
|
|
|
+| 编译状态 | ✅ BUILD SUCCESS |
|
|
|
+
|
|
|
+**结论:** 编译通过。467 个测试因 `@SpringBootTest` 需要 MySQL 数据库连接(`192.168.16.251:3306`)而无法执行上下文加载。46 个纯 Mockito 单元测试全部通过。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 二、测试通过情况(46 个测试,4 个测试类)
|
|
|
+
|
|
|
+| 测试类 | 测试方法数 | 状态 | 说明 |
|
|
|
+|--------|-----------|------|------|
|
|
|
+| `PdfParseServiceTest` | 10 | ✅ 通过 | PDF 解析服务,无 DB 依赖 |
|
|
|
+| `NutritionDeficiencyServiceTest` | 14 | ✅ 通过 | 营养缺陷服务,无 DB 依赖 |
|
|
|
+| `FoodServiceTest` | 12 | ✅ 通过 | 食品服务,无 DB 依赖 |
|
|
|
+| `ArticleServiceTest` | 10 | ✅ 通过 | 文章服务,MockMvc 风格纯单元测试 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 三、测试失败分析(467 个错误)
|
|
|
+
|
|
|
+### 3.1 根本原因
|
|
|
+
|
|
|
+所有错误均为 **同一根本原因**:
|
|
|
+
|
|
|
+```
|
|
|
+java.lang.IllegalStateException: Failed to load ApplicationContext
|
|
|
+ Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
|
|
|
+ Caused by: java.net.ConnectException: Connection refused: connect
|
|
|
+```
|
|
|
+
|
|
|
+`@SpringBootTest` 启动完整 Spring 上下文,需要连接 MySQL `192.168.16.251:3306`。本地开发环境无此数据库访问权限。
|
|
|
+
|
|
|
+### 3.2 附带问题:Bean 名称冲突
|
|
|
+
|
|
|
+测试还暴露了一个 Spring Bean 名称冲突(已修复):
|
|
|
+
|
|
|
+```
|
|
|
+org.springframework.context.annotation.ConflictingBeanDefinitionException:
|
|
|
+ Annotation-specified bean name 'userAddressController' for bean class
|
|
|
+ [com.etotem.cfc.controller.user.UserAddressController] conflicts with
|
|
|
+ existing, non-compatible bean definition of same name and class
|
|
|
+ [com.etotem.cfc.controller.UserAddressController]
|
|
|
+```
|
|
|
+
|
|
|
+**修复:** 给 `com.etotem.cfc.controller.UserAddressController` 添加显式 Bean 名称:
|
|
|
+```java
|
|
|
+@RestController("legacyUserAddressController")
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 四、编译错误修复(本次提交修复的所有问题)
|
|
|
+
|
|
|
+### 4.1 主代码编译错误(全部已修复)
|
|
|
+
|
|
|
+| 文件 | 错误类型 | 修复内容 |
|
|
|
+|------|---------|---------|
|
|
|
+| `DatabaseInitializer.java` | 大括号不匹配 | 补全 numsoul_config 和 user_address 的 catch 块闭合 |
|
|
|
+| `FamilyMemberVO.java` | 重复字段 | 删除 duplicate `memberType`/`danLevel` 字段 |
|
|
|
+| `HealthReportController.java` | 变量名错误 | `matchedChildId` → `userId` |
|
|
|
+| `TaskReminderService.java:151,274` | Long×int 溢出 | `(int)(completedTasks * 100L / totalTasks.intValue())` |
|
|
|
+| `ArticleService.java:377` | int→Double 类型转换 | `dto.setProgress((double) progress)` |
|
|
|
+| `ReportParseService.java:133,78` | Lombok Builder 类型引用 | 显式 Builder 类型 + cast to avoid annotation ordering issue |
|
|
|
+| `FamilyMemberAttributeService.java` | double/Long 类型问题 | 内部计算 double → int/Long |
|
|
|
+| `TraditionalMirrorController.java` | Double→Long | `Double.parseDouble` → `Long.parseLong` |
|
|
|
+| `AssessmentAdminController.java` | Double→Integer | 元转分,整数存储 |
|
|
|
+| `AssessmentService.java` | 方法签名 Double→Integer | 移除 ×100 转换 |
|
|
|
+| `AssessmentServiceInterface.java` | 方法签名 Double→Integer | 同上 |
|
|
|
+| `GuideApplication.java` | Lombok 兼容性问题 | 添加显式 setter/getter |
|
|
|
+| `UserAddressController.java` | Bean 名称冲突 | `@RestController("legacyUserAddressController")` |
|
|
|
+
|
|
|
+### 4.2 测试代码编译错误(全部已修复)
|
|
|
+
|
|
|
+| 文件 | 错误类型 | 修复内容 |
|
|
|
+|------|---------|---------|
|
|
|
+| `ProductOrderControllerTest.java:108,110,124,138` | 泛型类型不匹配 | `Result<ProductOrderDTO>` → `Result<Map<String, Object>>` |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 五、设计与实现差异分析
|
|
|
+
|
|
|
+### 5.1 架构层设计
|
|
|
+
|
|
|
+根据 `cfc-backend/AGENTS.md` 文档:
|
|
|
+
|
|
|
+- **分层架构:** Controller → Service → Mapper ✓(符合)
|
|
|
+- **响应包装:** 统一 `Result<T>` ✓(符合)
|
|
|
+- **认证:** JWT Token ✓(符合)
|
|
|
+- **接口方法:** 统一 `@PostMapping` ✓(符合)
|
|
|
+
|
|
|
+### 5.2 发现的问题
|
|
|
+
|
|
|
+#### 问题 1: 双 UserAddressController 存在重复功能
|
|
|
+- `com.etotem.cfc.controller.UserAddressController`(legacy)
|
|
|
+- `com.etotem.cfc.controller.user.UserAddressController`(新)
|
|
|
+
|
|
|
+两者映射到相同路径 `/api/user/address`,功能部分重叠。建议后续合并。
|
|
|
+
|
|
|
+#### 问题 2: 测试使用 @SpringBootTest 违反项目约定
|
|
|
+- `cfc-backend/AGENTS.md` 规定:"纯 Mockito 单元测试(无 `@SpringBootTest`,避免 MySQL 连接)"
|
|
|
+- 现有 40 个测试类中,大部分使用 `@SpringBootTest` + `@MockBean`
|
|
|
+- 这导致测试必须依赖真实数据库,无法在本地/CI 环境独立运行
|
|
|
+
|
|
|
+**建议:** 将 `@SpringBootTest` 测试重构为纯 Mockito 单元测试(不需要 DB 连接)。
|
|
|
+
|
|
|
+#### 问题 3: 测试基础设施不完整
|
|
|
+- `src/test/resources/` 不存在
|
|
|
+- 无 H2 内存数据库配置
|
|
|
+- 无测试数据 fixture
|
|
|
+- 无测试隔离机制
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 六、建议改进项
|
|
|
+
|
|
|
+### 高优先级
|
|
|
+
|
|
|
+1. **【测试重构】** 将 `@SpringBootTest` 改为纯 Mockito 单元测试
|
|
|
+ - 移除 `@SpringBootTest` 注解
|
|
|
+ - 使用 `@ExtendWith(MockitoExtension.class)`
|
|
|
+ - Mock 所有外部依赖(Service、Mapper)
|
|
|
+ - 目标:46 个通过测试 → 513 个通过
|
|
|
+
|
|
|
+2. **【Bean 冲突】** 评估两个 UserAddressController 的功能差异,合并或删除重复
|
|
|
+
|
|
|
+### 中优先级
|
|
|
+
|
|
|
+3. **【测试数据】** 添加 `src/test/resources/application-test.yml`,配置 H2 内存数据库
|
|
|
+4. **【CI 流水线】** 添加 Maven test 到 CI,确保编译和单元测试通过
|
|
|
+
|
|
|
+### 低优先级
|
|
|
+
|
|
|
+5. **【测试覆盖率】** 添加 JaCoCo 覆盖率报告
|
|
|
+6. **【集成测试】** 添加带真实 DB 的集成测试(仅在 CI 环境运行)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 七、结论
|
|
|
+
|
|
|
+| 检查项 | 状态 |
|
|
|
+|--------|------|
|
|
|
+| 编译通过 | ✅ |
|
|
|
+| 单元测试(46个) | ✅ 全部通过 |
|
|
|
+| 集成测试(467个) | ⚠️ 需要 MySQL 数据库 |
|
|
|
+| Bean 冲突修复 | ✅ |
|
|
|
+| 测试基础设施 | ⚠️ 需完善 |
|
|
|
+
|
|
|
+**本次提交内容:**
|
|
|
+- 所有编译错误修复(主代码 + 测试代码)
|
|
|
+- Bean 名称冲突修复(Spring 上下文加载问题)
|
|
|
+- 测试报告生成
|
|
|
+
|
|
|
+**待办:**
|
|
|
+- 重构 467 个测试为纯 Mockito 单元测试
|
|
|
+- 配置测试数据库(H2)
|
|
|
+- 完善 CI 流水线
|