为何基于Mockito编写的测试能在任意随机入参下通过,即便加法结果非恒为3?
核心原因拆解
你会有这个疑问,核心是把Mockito生成的Mock假对象和带真实计算逻辑的实体搞混了——这个测试从始至终就没跑过真实的加法运算流程,随机数是什么值根本不影响最终结果。
你测试里的calculator根本不是“真实计算器”
你在测试代码里拿到的calculator实例,是Mockito框架替你生成的、没有任何真实业务逻辑的代理假对象。你写的这行打桩代码:
when(calculator.add(any(Integer.class), any(Integer.class))).thenReturn(3);
根本不是去修改真实计算器的加法规则,而是给这个假对象提前写死了响应规则:
- 只要有任何代码调用这个假对象的
add()方法,不管传入的两个参数是什么值——哪怕是随机生成的、哪怕是超大整数、哪怕是负数 - 假对象会直接跳过所有真实运算流程,无脑返回你指定的固定值3,完全不会真的把两个传入的整数加起来算结果
测试流程里根本没触发真实加法计算
你调用classUnderTest.calculate(...)的时候,这个待测的业务类在处理加法类型请求时,会调用它内部持有的calculator实例的add()方法。但这个calculator就是前面说的那个被你配置好返回值的假对象,所以不管你传进去的两个随机整数实际和是多少,拿到的add返回值永远是写死的3。
这个测试真正在测的内容
很多新手第一次见这种用例会有认知偏差,误以为这是在测加法计算的正确性,实际上它完全是在测你自己写的业务类的分支逻辑是否靠谱:
- 当计算类型标记为加法时,业务类有没有正确调用计算器的
add方法(对应verify(calculator, times(1)).add(...)的校验) - 业务类有没有写错分支,在加法场景下乱调用减法、乘法等其他方法(对应
verify(calculator, never()).sub(...)的校验) - 业务类有没有正确把计算器返回的结果往外传递(对应
assertThat(result).isEqualTo(3)的校验)
可以做个简单的验证:如果你把测试里的
calculator换成你自己写的、带真实加法逻辑的普通Calculator实例,不做任何mock打桩,这个测试大概率一跑就挂——那时候add方法会真的计算两个随机数的和,结果根本不可能恒等于3。
内容的提问来源于stack exchange,提问作者Mitch
相关产品推荐
相关产品推荐

