整洁架构(DDD)中用例单元测试的实体依赖如何管理
核心原则先行
首先纠正一个普遍的认知误区:单元测试的「单元」从来不是指单个类,而是单个可独立验证的、无外部IO副作用的业务逻辑单元。在DDD/整洁架构的语境下,同属领域层的实体、值对象是领域规则的载体,本身就是业务逻辑的组成部分,不属于需要隔离的外部依赖。
针对实体依赖的通用处理原则非常明确:
- 仅对跨边界的IO类依赖(仓储、RPC接口、第三方服务、配置中心等)做Mock/Stub
- 同领域层内无副作用的实体、值对象、领域服务,直接使用真实实例,不需要Mock
- 实体自身的逻辑必须单独编写单元测试全量覆盖,确保实体逻辑的正确性,从根源避免「实体bug导致上层用例测试误报」的问题——哪怕真的出现这种情况,也不是误报,而是测试帮你提前发现了实体逻辑的缺陷,本来就需要修复
- 只有当实体设计不合理、内部夹带了IO调用等副作用时,才需要考虑Mock实体,这种情况优先重构实体把副作用移到应用层/基础设施层,而非妥协Mock实体
对三类待选方案的误区澄清
- 方案1(注入Fake实体):完全本末倒置。实体本身就是你要验证的业务逻辑的一部分,Mock实体等于把你需要校验的核心逻辑替换成了假实现,测试完全失去有效性,还会额外增加大量维护成本,属于完全不可取的方案。
- 方案2(不Mock实体):这是正确的方向,你对「集成测试」的判断有误。集成测试的核心是验证跨边界、跨层的交互逻辑(比如用例调用真实仓储读写数据库),同属领域层的多个逻辑组件一起测试,本身就是单元测试的合理范围,不存在所谓的「测试范围过大」问题。
- 方案3(重构生产代码解耦实体):完全没有必要。只要实体是纯领域逻辑、无外部IO依赖,本身就和用例是内聚的领域逻辑单元,不需要为了测试强行解耦。
示例场景的单元测试实现
你给出的addHorseUseCase场景中,唯一需要Mock的只有跨边界的HorseRepo依赖,HorseEntity直接使用真实实例即可,必要时可以用Spy监听实体方法的调用,不需要替换实体的真实实现。
以下是测试伪代码示例:
# 场景1:健康检查不通过,新增马匹失败 def test_add_horse_failed_when_health_unqualified(): # 仅Mock仓储依赖 mock_repo = Mock() use_case = AddHorseUseCase() req = AddHorseReq(name="枣红马", age=4, health_status="sick") result = use_case.execute(req, mock_repo, HorseEntity) # 验证返回错误 assert result.err_code == "HEALTH_CHECK_FAILED" # 验证仓储未被调用 mock_repo.save.assert_not_called() # 场景2:健康检查通过,新增马匹成功 def test_add_horse_success(): mock_repo = Mock() use_case = AddHorseUseCase() req = AddHorseReq(name="枣红马", age=4, health_status="healthy") # 对实体方法打Spy,仅监听调用,不替换实现 spy_check_health = spy(HorseEntity, "checkHealth") spy_make_shoeing = spy(HorseEntity, "makeShoeing") spy_equip_saddle = spy(HorseEntity, "equipSaddle") result = use_case.execute(req, mock_repo, HorseEntity) # 验证执行成功 assert result.is_success() # 验证实体方法按预期顺序调用 assert spy_check_health.called_once() assert spy_make_shoeing.called_once() assert spy_equip_saddle.called_once() # 验证仓储被正确调用,参数符合预期 mock_repo.save.assert_called_once() saved_horse = mock_repo.save.call_args[0][0] assert saved_horse.name == "枣红马" assert saved_horse.has_shoe == True assert saved_horse.has_saddle == True
内容的提问来源于stack exchange,提问作者Ecora
相关产品推荐
相关产品推荐

