重构多if-else:如何拆分PIN验证逻辑以提升可测试性?
拆分PIN验证逻辑以简化单元测试
你的这段PIN验证代码混合了数据查询、PIN初始化、匹配校验、失败状态更新等多个职责,导致单元测试需要mock仓储、处理复杂分支逻辑,测试成本很高。我们可以按照单一职责原则拆分成多个小方法,每个方法只负责一件事,这样每个部分都能独立测试,无需依赖整个仓储上下文。
拆分核心思路
把业务逻辑判断、计算和仓储操作分离:
- 纯业务逻辑方法:只接收参数、执行判断/计算,不依赖仓储,方便单独测试
- 仓储操作方法:专门负责与数据库交互,测试时只需mock这些方法的返回
重构后的代码示例
public async Task<ResultTypes> ValidatePinAsync(int id, string pin) { var customer = await _repository.GetCustomer(id); // 检查PIN是否已禁用 if (IsPinDisabled(customer)) return ResultTypes.PinDisabled; // 处理未设置PIN的情况 if (string.IsNullOrEmpty(customer.PinNumber)) { await InitializeDefaultPin(customer); return await HandlePinVerificationResult(customer, pin); } // 已有PIN的校验逻辑 return await HandlePinVerificationResult(customer, pin); } // 纯逻辑:检查PIN是否禁用 private bool IsPinDisabled(ICustomer customer) { return customer.PinDisabled; } // 业务逻辑+仓储操作:初始化默认PIN private async Task InitializeDefaultPin(ICustomer customer) { customer.PinNumber = customer.DoB.ToString(); await _repository.UpdateCustomer(customer); } // 核心校验逻辑:处理PIN匹配/不匹配的结果 private async Task<ResultTypes> HandlePinVerificationResult(ICustomer customer, string pin) { if (IsPinMatching(customer, pin)) return ResultTypes.Success; // 处理验证失败的逻辑 return await HandlePinVerificationFailure(customer); } // 纯逻辑:判断PIN是否匹配 private bool IsPinMatching(ICustomer customer, string pin) { return customer.PinNumber == pin; } // 业务逻辑+仓储操作:处理验证失败后的状态更新 private async Task<ResultTypes> HandlePinVerificationFailure(ICustomer customer) { customer.FailureCount++; // 判断是否需要禁用PIN(示例:3次失败触发禁用) if (customer.FailureCount >= 3) { customer.PinDisabled = true; await _repository.UpdateCustomer(customer); return ResultTypes.PinDisabled; } await _repository.UpdateCustomer(customer); return ResultTypes.InvalidPinEntered; }
拆分后的测试优势
- 纯逻辑方法可独立测试:比如
IsPinMatching、IsPinDisabled,只需传入不同的ICustomer和pin参数,无需mock任何仓储,直接验证返回结果 - 仓储依赖方法只需mock交互:比如
InitializeDefaultPin,只需验证是否调用了_repository.UpdateCustomer,以及传入的customer是否正确设置了PIN - 分支逻辑更清晰:每个小方法只处理一个分支,测试时可以针对每个分支单独编写用例,覆盖所有场景(比如未设置PIN时的成功/失败、已有PIN的成功/失败、失败次数达上限禁用等)
内容的提问来源于stack exchange,提问作者user1890098
相关产品推荐
相关产品推荐

