# Cypress Mock Handlers 使用文档 本目录包含所有 Cypress 测试的 API mock handlers,用于模拟后端接口响应。 ## 目录结构 ``` cypress/support/mock/ ├── handlers/ # Mock handler 文件 │ ├── system.ts # 系统信息相关 │ ├── i18n.ts # 国际化相关 │ ├── user.ts # 用户相关 │ ├── auth.ts # 认证相关 │ ├── resource.ts # 资源配置相关 │ ├── protocol.ts # 协议相关 │ ├── study.ts # 检查信息管理 │ ├── image.ts # 图像相关 │ ├── report.ts # 报告相关 │ ├── device.ts # 设备相关 │ ├── exam.ts # 检查执行相关 │ └── quota.ts # 配额相关 ├── index.ts # 统一导出 └── README.md # 本文档 ``` ## 快速开始 ### 1. 导入 Mock Handlers 在测试文件中导入需要的 mock handlers: ```typescript import { mockLoginSuccess, mockGetSoftwareInfoSuccess, mockI18nSuccess, } from '../support/mock'; ``` ### 2. 在测试中使用 ```typescript describe('登录功能测试', () => { beforeEach(() => { // 设置 mock mockLoginSuccess(); mockGetSoftwareInfoSuccess(); }); it('应该成功登录', () => { cy.visit('/login'); cy.get('[data-testid="username"]').type('admin'); cy.get('[data-testid="password"]').type('123456'); cy.get('[data-testid="login-btn"]').click(); // 等待并验证 mock 响应 cy.wait('@loginSuccess'); cy.url().should('include', '/dashboard'); }); }); ``` ## 模块说明 ### System - 系统信息 ```typescript import { mockGetSoftwareInfoSuccess } from '../support/mock'; // 使用 mockGetSoftwareInfoSuccess(); cy.wait('@getSoftwareInfoSuccess'); ``` **可用函数:** - `mockGetSoftwareInfoSuccess()` - 获取软件信息成功 - `mockGetSoftwareInfoFail()` - 获取软件信息失败 ### I18n - 国际化 ```typescript import { mockGetLanguageListSuccess, mockI18nSuccess } from '../support/mock'; // 获取语言列表 mockGetLanguageListSuccess(); // 获取翻译文件 mockI18nSuccess('zh'); // 或 'en' ``` **可用函数:** - `mockGetLanguageListSuccess()` - 获取语言列表成功 - `mockGetLanguageListEmpty()` - 获取空语言列表 - `mockI18nSuccess(locale)` - 获取翻译文件成功 - `mockI18nError(locale)` - 获取翻译文件失败(404) - `mockI18nServerError(locale)` - 服务器错误(500) - `mockI18nTimeout(locale)` - 请求超时 - `mockI18nInvalidFormat(locale)` - 返回无效格式 - `mockI18nEmptyData(locale)` - 返回空数据 - `mockI18nNetworkError(locale)` - 网络错误 ### User - 用户 ```typescript import { mockLoginSuccess, mockGetUsersSuccess } from '../support/mock'; // 登录 mockLoginSuccess(); // 获取用户列表 mockGetUsersSuccess(); ``` **可用函数:** - `mockLoginSuccess()` - 登录成功 - `mockLoginFail()` - 登录失败(用户名或密码错误) - `mockGetUsersSuccess()` - 获取用户列表成功 - `mockGetUsersEmpty()` - 获取空用户列表 ### Auth - 认证 ```typescript import { mockChangePasswordSuccess } from '../support/mock'; mockChangePasswordSuccess(); cy.wait('@changePasswordSuccess'); ``` **可用函数:** - `mockChangePasswordSuccess()` - 修改密码成功 - `mockChangePasswordWrongOldPassword()` - 旧密码错误 - `mockChangePasswordNotMatch()` - 新密码不匹配 ### Resource - 资源配置 ```typescript import { mockGetOptionsSexFull, mockGetImageSuccess } from '../support/mock'; // 获取性别选项 mockGetOptionsSexFull(); // 获取示意图 mockGetImageSuccess(); ``` **可用函数:** - `mockGetOptionsSexFull()` - 获取性别选项 - `mockGetOptionsPatientSize()` - 获取患者体型选项 - `mockGetConfigSimulatorGEN()` - 获取发生器仿真配置 - `mockGetConfigSimulatorFPD()` - 获取探测器仿真配置 - `mockGetImageSuccess()` - 获取示意图成功 - `mockGetImageNotFound()` - 示意图不存在(404) ### Protocol - 协议 ```typescript import { mockGetPatientTypeHuman, mockGetBodyPartHuman, mockGetProcedureListSuccess, } from '../support/mock'; // 获取患者类型 mockGetPatientTypeHuman(); // 获取身体部位 mockGetBodyPartHuman(); // 获取协议列表 mockGetProcedureListSuccess(); ``` **可用函数:** - `mockGetPatientTypeHuman()` - 获取人医患者类型 - `mockGetPatientTypeAll()` - 获取所有患者类型 - `mockGetBodyPartHuman()` - 获取人医身体部位 - `mockGetProcedureListSuccess()` - 获取协议列表 - `mockGetViewListSuccess()` - 获取体位列表 - `mockGetViewDetailSuccess()` - 获取体位详情 - `mockGetAprByViewSuccess()` - 获取APR详情(通过view_id) - `mockGetAprDeviceSuccess()` - 获取APR设备信息 - `mockGetAprTechParamsSuccess()` - 获取APR默认曝光参数 ### Study - 检查信息管理 ```typescript import { mockRegisterStudySuccess, mockGetStudyArrived, mockUpdateStudySuccess, } from '../support/mock'; // 登记检查 mockRegisterStudySuccess(); // 获取检查信息 mockGetStudyArrived(); // 更新检查信息 mockUpdateStudySuccess(); ``` **可用函数:** - `mockRegisterStudySuccess()` - 登记检查成功 - `mockGetStudyArrived()` - 获取检查信息(Arrived状态) - `mockGetStudyStatSuccess()` - 获取检查统计信息 - `mockUpdateStudySuccess()` - 更新检查信息成功 - `mockDeleteStudyBatchSuccess()` - 批量删除检查成功 - `mockStorePortraitSuccess()` - 存储急诊患者影像成功 - `mockLeaveStudyInProgress()` - 挂起检查 - `mockLeaveStudyCompleted()` - 完成检查 ### Image - 图像 ```typescript import { mockAppendImagesSuccess, mockDeleteImageSuccess, } from '../support/mock'; // 添加体位 mockAppendImagesSuccess(); // 删除体位 mockDeleteImageSuccess(); ``` **可用函数:** - `mockAppendImagesSuccess()` - 批量添加体位成功 - `mockCopyImageSuccess()` - 复制体位成功 - `mockSortImagesSuccess()` - 体位重新排序成功 - `mockDeleteImageSuccess()` - 删除体位成功 - `mockStorePostProcSuccess()` - 存储后处理DCM成功 - `mockGetDcmFileSuccess()` - 获取DCM文件成功 - `mockGetThumbnailSuccess()` - 获取缩略图成功 ### Report - 报告 ```typescript import { mockReportPreviewSuccess, mockSaveReportSuccess, } from '../support/mock'; // 预览报告 mockReportPreviewSuccess(); // 保存报告 mockSaveReportSuccess(); ``` **可用函数:** - `mockReportPreviewSuccess()` - 报告预览成功 - `mockSaveReportSuccess()` - 保存报告成功 - `mockGetReportSuccess()` - 获取报告成功 - `mockGetReportNotFound()` - 报告不存在(404) ### Device - 设备 ```typescript import { mockOpenDeviceSuccess, mockDeviceGetSuccess, mockDeviceActionSuccess, } from '../support/mock'; // 打开设备 mockOpenDeviceSuccess(); // 获取设备状态 mockDeviceGetSuccess(); // 执行设备动作 mockDeviceActionSuccess(); ``` **可用函数:** - `mockOpenDeviceSuccess()` - 打开设备成功 - `mockDeviceGetSuccess()` - 执行Get操作成功 - `mockDeviceActionSuccess()` - 执行Action操作成功 ### Exam - 检查执行 ```typescript import { mockStartInspectionSuccess, mockGetGlobalStatusAllReady, mockTriggerInspectionSuccess, } from '../support/mock'; // 开始检查 mockStartInspectionSuccess(); // 获取全局状态 mockGetGlobalStatusAllReady(); // 触发曝光 mockTriggerInspectionSuccess(); ``` **可用函数:** - `mockStartInspectionSuccess()` - 开始检查成功 - `mockGetGlobalStatusAllReady()` - 获取全局状态(全部就绪) - `mockGetGlobalStatusNotReady()` - 获取全局状态(未就绪) - `mockTriggerInspectionSuccess()` - 软曝光成功 - `mockJudgeImageAccept()` - 接受图像 - `mockJudgeImageReject()` - 拒绝图像 ### Quota - 配额 ```typescript import { mockQuotaSufficient, mockQuotaInsufficient } from '../support/mock'; // 配额充足 mockQuotaSufficient(); // 配额不足 mockQuotaInsufficient(); ``` ## 完整示例 ### 示例1:登录流程测试 ```typescript import { mockLoginSuccess, mockGetSoftwareInfoSuccess, mockI18nSuccess, mockGetLanguageListSuccess, } from '../support/mock'; describe('登录流程', () => { beforeEach(() => { // 设置所有必要的 mocks mockGetSoftwareInfoSuccess(); mockGetLanguageListSuccess(); mockI18nSuccess('zh'); mockLoginSuccess(); }); it('应该成功登录并跳转到主页', () => { cy.visit('/login'); // 填写登录表单 cy.get('[data-testid="username"]').type('admin'); cy.get('[data-testid="password"]').type('123456'); cy.get('[data-testid="login-btn"]').click(); // 验证请求 cy.wait('@loginSuccess').its('response.statusCode').should('eq', 200); // 验证跳转 cy.url().should('include', '/dashboard'); }); }); ``` ### 示例2:患者登记测试 ```typescript import { mockGetPatientTypeHuman, mockGetBodyPartHuman, mockGetProcedureListSuccess, mockRegisterStudySuccess, } from '../support/mock'; describe('患者登记', () => { beforeEach(() => { mockGetPatientTypeHuman(); mockGetBodyPartHuman(); mockGetProcedureListSuccess(); mockRegisterStudySuccess(); }); it('应该成功登记患者', () => { cy.visit('/patient/register'); // 填写患者信息 cy.get('[name="patient_name"]').type('测试患者'); cy.get('[name="patient_id"]').type('P001'); // 选择协议 cy.get('[data-testid="select-protocol"]').click(); cy.wait('@getProcedureListSuccess'); // 提交 cy.get('[data-testid="submit-btn"]').click(); cy.wait('@registerStudySuccess'); // 验证成功提示 cy.contains('登记成功').should('be.visible'); }); }); ``` ### 示例3:曝光流程测试 ```typescript import { mockStartInspectionSuccess, mockGetGlobalStatusAllReady, mockTriggerInspectionSuccess, mockJudgeImageAccept, } from '../support/mock'; describe('曝光流程', () => { beforeEach(() => { mockStartInspectionSuccess(); mockGetGlobalStatusAllReady(); mockTriggerInspectionSuccess(); mockJudgeImageAccept(); }); it('应该成功完成曝光', () => { cy.visit('/exam/exposure'); // 等待设备就绪 cy.wait('@getGlobalStatusAllReady'); cy.get('[data-testid="ready-indicator"]').should('have.class', 'ready'); // 触发曝光 cy.get('[data-testid="trigger-btn"]').click(); cy.wait('@triggerInspectionSuccess'); // 接受图像 cy.get('[data-testid="accept-btn"]').click(); cy.wait('@judgeImageAccept'); // 验证成功 cy.contains('图像已保存').should('be.visible'); }); }); ``` ## 注意事项 1. **Mock 顺序**:在 `beforeEach` 中设置 mock,确保每个测试都有干净的状态 2. **等待响应**:使用 `cy.wait('@aliasName')` 等待 mock 响应,避免时序问题 3. **验证响应**:可以验证 mock 响应的状态码和数据: ```typescript cy.wait('@loginSuccess').its('response.statusCode').should('eq', 200); ``` 4. **组合使用**:根据测试场景组合使用多个 mock handlers 5. **清理**:Cypress 会在每个测试后自动清理 intercept,无需手动清理 ## 参考文档 - API 文档:`docs/DR.md` - Cypress 官方文档:https://docs.cypress.io/ - Intercept 文档:https://docs.cypress.io/api/commands/intercept ## 贡献 添加新的 mock handler 时,请遵循以下规范: 1. 使用统一的 JSDoc 注释格式 2. 包含完整的参数和返回值说明 3. 提供使用示例 4. 在 `index.ts` 中导出 5. 更新本文档