被设定抛出异常的Test Double仍属Stub吗?基于Martin Fowler/xUnit定义
基于Martin Fowler测试替身定义的结论:这是Stub,不是Mock
根据Martin Fowler在xUnit测试模式中的定义,测试替身(Test Double)是一个统称,其下的Stub和Mock有明确的核心区分:
- Stub:为被测系统(SUT)提供预设的响应(包括返回值、抛出异常),目的是让SUT能够完成执行,测试的关注点是SUT的输出结果,而非与Stub的交互过程。Stub的行为可以是条件化的(比如根据不同输入返回不同内容),但本质仍是硬编码的预设逻辑。
- Mock:核心特征是验证与SUT的交互是否符合预期,除了提供预设响应外,必须通过
verify类操作来确认SUT是否按正确的方式调用了依赖(比如调用次数、参数是否正确),测试的关注点是交互过程而非SUT的输出结果。
结合你的代码分析:
- 你对Stub的判断是准确的:
planetServiceTestDouble的作用是为PlanetDensityCalculator提供硬编码的预设响应(正确行星返回实例、错误行星抛出异常),目的是让计算器能完成计算流程,测试的目标是验证计算器的输出(比如正确密度、负密度),完全符合Stub的定义。同事提到的“按条件抛出异常”是Stub允许的行为,并非Mock的专属特征。 - 你的第二个反驳点完全站得住脚:当前代码中没有任何
Mockito.verify()调用,完全没有对PlanetDensityCalculator与planetServiceTestDouble的交互进行验证,而这正是Mock的核心要求。哪怕用了Mockito的mock()方法创建对象,只要没有做交互验证,它就只是Stub而非Mock——Mockito的mock()只是创建测试替身的工具,对象的角色由你的使用方式决定。
内容的提问来源于stack exchange,提问作者Kirill
相关产品推荐
相关产品推荐

