# Week 8:工程化能力 **目标**:掌握测试、文档、部署等工程化技能,交付可测试、有文档、容器化的完整项目。 **前置**:完成 Week 7(前后端分离项目)。 **本周产出**:学生管理系统 v4 — 有单元测试、集成测试、API 文档。 **启动方式**: ```bash cd week8 # 运行测试 mvn test # 启动应用后访问 API 文档 http://localhost:8080/doc.html ``` --- ## Day 1:JUnit 5 + Mockito 单元测试 **知识点**: - 测试金字塔:单元测试 → 集成测试 → E2E 测试 - JUnit 5 注解:`@Test`、`@BeforeEach`、`@DisplayName` - 断言:`assertEquals`、`assertTrue`、`assertThrows` - Mockito:`@Mock`(模拟依赖)、`@InjectMocks`(注入模拟对象) - `when(...).thenReturn(...)`:控制 Mock 行为 - `verify()`:验证方法被调用 - `@ExtendWith(MockitoExtension.class)`:初始化 Mockito - 测试覆盖率:行覆盖 vs 分支覆盖 **动手 → 理解**: 1. 阅读 `AuthServiceTest.java`,理解每个 `@Mock` 的含义 2. 运行 `mvn test -Dtest=AuthServiceTest`,观察 5 个测试全部通过 3. 故意把 `testLoginBadPassword` 的期望密码改为正确值,观察测试失败信息 4. 在 `when(...)` 中把返回值改成 `false`,看哪个测试会失败 5. 写一个测试:验证 `register` 成功时 `userRepo.save()` 被调用了 1 次 **核心文件**: - `src/test/java/com/learn/service/AuthServiceTest.java` — 单元测试示例 **思考题**:为什么不直接测试 Service 的真实数据库操作,而是用 Mockito 模拟? --- ## Day 2:@SpringBootTest 集成测试 **知识点**: - `@SpringBootTest`:启动完整 Spring 容器 - `@AutoConfigureMockMvc`:模拟 HTTP 请求 - `MockMvc`:`perform(get(...))`、`andExpect(status().isOk())`、`jsonPath()` - H2 内存数据库:`jdbc:h2:mem:testdb` — 不依赖外部 MySQL - `@ActiveProfiles("test")`:测试专用配置 - `application-test.yml`:测试环境的 H2 + 禁用 Redis - `@TestMethodOrder` + `@Order`:控制测试顺序 **动手 → 理解**: 1. 阅读 `StudentControllerTest.java`,理解测试流程 2. 运行 `mvn test`,观察 Spring Boot 启动日志中的 `Using profile: "test"` 3. 在测试日志中找到 H2 的 `HikariPool-1 - Starting...` 确认使用内存库 4. 访问 `http://localhost:8080/h2-console`(测试模式下),查看表结构 5. 添加一个测试:验证用 user/123456(USER 角色)新增学生时返回 403 **核心文件**: - `src/test/java/com/learn/controller/StudentControllerTest.java` — 集成测试 - `src/main/resources/application-test.yml` — 测试环境配置 **思考题**:H2 和 Testcontainers(真实 MySQL 容器)各有什么优劣?什么时候该用 Testcontainers? --- ## Day 3:Knife4j API 文档 **知识点**: - 为什么需要 API 文档:前后端协作、接口调试、新人上手 - Swagger / OpenAPI 3.0 规范 - Knife4j:国产增强版 Swagger UI(界面更友好) - `@Tag`、`@Operation`、`@Parameter` 注解增强文档 - `application.yml` 配置:`springdoc.swagger-ui.path=/doc.html` - `OpenAPI` Bean:自定义文档标题、版本、描述 - 在线调试:在文档页面直接发送请求 **动手 → 理解**: 1. 启动项目,访问 `http://localhost:8080/doc.html` 2. 点击 "Auth" 标签,展开 `/api/auth/login`,点击"发送"直接测试 3. 在文档右上角设置全局 Token:`Bearer <你的JWT>` 4. 用文档页面的"调试"功能完成一次完整的增删改查 5. 在 Controller 方法上添加 `@Operation(summary = "...")` 注解,刷新文档查看效果 **核心文件**: - `config/Knife4jConfig.java` — API 文档配置 - `pom.xml` → `knife4j-openapi3-jakarta-spring-boot-starter` - `application.yml` → `springdoc.*` **思考题**:API 文档应该暴露在生产环境吗?如果不应该,怎么关闭? **生产环境安全提示**: ```yaml # 生产环境 application-prod.yml 中关闭文档 springdoc: api-docs: enabled: false # 关闭 /v3/api-docs swagger-ui: enabled: false # 关闭 /doc.html ``` 或在 SecurityConfig 中按 Profile 条件放行: ```java // 开发环境放行文档,生产环境不放行 @Profile("!prod") ``` **原则**:API 文档暴露所有接口结构和参数,生产环境应关闭或加认证保护。 --- ## Day 4:阶段总结 & 里程碑项目 v4 **知识点**: - 回顾 Week 1-8 的技术栈全景图 - 理解"测试金字塔"在项目中的落地 - 对比 v1 → v4 四个版本的进化 **v1 → v4 进化史**: | 版本 | 周次 | 新增能力 | |------|------|---------| | v1 | Week 4 | Spring Boot + JPA/MP + 原生 JS 全栈 | | v2 | Week 5 | Spring Security + JWT + Redis + Actuator | | v3 | Week 7 | Vue 3 前后端分离 + Axios + 导航守卫 | | v4 | Week 8 | 单元测试 + 集成测试 + API 文档 | **Actuator 端点说明**(Week 5 遗留问题): - `/actuator` — 返回所有**可用端点列表**的 JSON,这是正常的 - 真正的监控数据在这些端点: - `/actuator/health` → 健康状态(UP/DOWN) - `/actuator/beans` → Spring 容器中所有 Bean - `/actuator/env` → 环境变量和配置 - `/actuator/mappings` → 所有 URL 映射 - **安全建议**:`/actuator/env` 可能泄露数据库密码等敏感信息,生产环境不应暴露 **动手 → 理解**: 1. 画出 v4 的完整架构图(Vue → Axios → Spring Boot → JPA/MP → MySQL) 2. 检查所有测试是否通过:`mvn test` 3. 检查 API 文档是否完整:`http://localhost:8080/doc.html` 4. 确认 `docker-compose up --build` 能成功启动 5. 补充 `.gitignore`、`README.md` **最终项目文件清单**: ``` week8/ ├── pom.xml # 含 test + knife4j 依赖 ├── sql/init.sql # 数据库初始化 ├── src/main/ │ ├── java/com/learn/ │ │ ├── config/ │ │ │ ├── Knife4jConfig.java # Day 3: API 文档 │ │ │ └── SecurityConfig.java # 含 CORS │ │ ├── controller/ # REST API │ │ ├── entity/ # Student + User │ │ └── service/ # 双 ORM 实现 │ └── resources/ │ ├── application.yml # 主配置 + springdoc │ └── application-test.yml # Day 2: H2 测试配置 └── src/test/java/com/learn/ ├── service/AuthServiceTest.java # Day 1: 单元测试 └── controller/StudentControllerTest.java # Day 2: 集成测试 ``` --- ## Week 8 总结 | 维度 | 工具 | 掌握程度 | |------|------|---------| | 单元测试 | JUnit 5 + Mockito | Service 层全 Mock 测试 | | 集成测试 | @SpringBootTest + H2 | Controller 全流程测试 | | API 文档 | Knife4j / SpringDoc | 自动生成 + 在线调试 | **下一阶段:Week 9-12 — AI Agent 开发** - Week 9:AI & LLM 基础,调用大模型 API - Week 10:Agent 架构 + Function Calling - Week 11:算法入门 + Agent 前端 - Week 12:最终项目 —— AI Agent 网站