咨询PowerMockito.when()与PowerMockito.doReturn()的适用场景及区别
PowerMockito.when() vs PowerMockito.doReturn():该选哪个?
嘿,这个问题绝对是Mockito/PowerMockito新手绕不开的坎儿,我当初刚用的时候也懵了好久,其实核心就俩字:是否触发真实方法调用。下面给你拆解清楚两者的适用场景:
先搞懂核心区别
PowerMockito.when():属于**“先执行,再存根”**的模式。它会先实际调用一次你要mock的方法,然后再指定后续调用的返回值。这意味着如果这个方法本身有副作用(比如改全局变量、调用数据库)或者会抛出异常,用它就会踩坑。PowerMockito.doReturn():属于**“直接存根,跳过执行”**的模式。它完全不会触发真实方法的调用,直接告诉PowerMockito“当这个方法被调用时,返回我指定的值”。
各自的适用场景
用PowerMockito.when()的情况
- 纯无副作用的方法存根:比如你mock的是一个只返回数据、不修改任何状态的工具类方法,调用它不会有任何额外影响。这时候用
when()的语法更直观,代码可读性更高。
示例:// mock一个返回字符串的工具类方法 MockedStatic<StringUtils> mockedStringUtils = PowerMockito.mockStatic(StringUtils.class); when(StringUtils.isEmpty(anyString())).thenReturn(false); - 非spy对象的普通mock:当你完全mock一个类(不是spy真实对象),这时候即使调用方法也不会触发真实逻辑,用
when()完全没问题。
必须用PowerMockito.doReturn()的情况
- 处理spy对象的存根:当你用
spy()包装真实对象,想要让某个方法返回指定值但不执行真实逻辑时,when()会先跑一遍真实方法,这大概率不是你想要的。比如:// spy一个真实的ArrayList List<String> spyList = PowerMockito.spy(new ArrayList<>()); // 错误示范:用when会先执行真实的add方法,spyList里会多一个元素 // when(spyList.add("test")).thenReturn(true); // 正确姿势:用doReturn跳过真实调用,spyList保持为空 doReturn(true).when(spyList).add("test"); - 被mock的方法调用会触发副作用/抛异常:比如你mock的方法本来会调用真实的API、操作数据库,或者本身就会抛出异常,用
when()会先触发这些操作,导致测试失败或污染环境。这时候doReturn()就能完美规避。 - mock final/private方法(且真实调用有风险):虽然PowerMockito支持用
when()处理final/private方法,但如果这些方法的真实执行会有问题(比如private方法里有未初始化的变量,调用就抛NPE),用doReturn()可以直接跳过真实逻辑,避免不必要的错误。 - void方法的特殊存根(比如跳过执行):虽然void方法更多用
doNothing(),但如果是要模拟void方法的“成功执行”且跳过真实逻辑,本质也是doReturn()的思路(不过void方法本身没有返回值,所以用doNothing().when(mock).voidMethod())。
总结
- 优先选
PowerMockito.when():语法自然,可读性强,适合绝大多数无风险的存根场景。 - 遇到spy对象、有副作用的方法、会抛异常的方法、final/private方法存根有风险这些情况,果断用
PowerMockito.doReturn()。
内容的提问来源于stack exchange,提问作者user14104736
相关产品推荐
相关产品推荐

