PowerMockito静态方法Mock:doReturn...When触发UnfinishedStubbingException问题
PowerMockito静态方法Stubbing异常原因解析
嘿,我来给你掰扯清楚这个问题!你遇到的UnfinishedStubbingException完全是因为PowerMockito中doReturn().when()针对静态方法的写法逻辑和实例方法不一样,咱们一步步拆解:
先看你的问题场景
你要模拟Cola类的静态drink()方法,用PowerMockito.when(Cola.drink()).thenReturn("Drinking")没问题,但换成PowerMockito.doReturn("Drinking").when(Cola.drink())就抛异常,对吧?
先把你的代码贴出来方便对照:
TestDrink.java
@RunWith(PowerMockRunner.class) @PrepareForTest({Drink.class,Cola.class}) public class TestDrink { @Test public void test() { PowerMockito.mockStatic(Cola.class); // 这个写法报错 PowerMockito.doReturn("Drinking") .when(Cola.drink()); System.out.println(Cola.drink()); } }
Cola.java
public class Cola { public static String drink() { return "No drinking"; } }
抛出的异常
org.mockito.exceptions.misusing.UnfinishedStubbingException: Unfinished stubbing detected here: -> at TestDrink.test(TestDrink.java:22) E.g. thenReturn() may be missing. Examples of correct stubbing: when(mock.isOk()).thenReturn(true); when(mock.isOk()).thenThrow(exception); doThrow(exception).when(mock).someVoidMethod(); Hints: 1. missing thenReturn() 2. you are trying to stub a final method, you naughty developer! 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed ...(后面堆栈省略)
核心原因:两种Stubbing写法的逻辑差异
PowerMockito继承了Mockito的语法,但针对静态方法做了适配,这两个写法的本质区别在于调用时机和参数传递:
1. when(Cola.drink()).thenReturn("Drinking") 为什么正常?
这个写法是Mockito的**“存根前调用”**语法:
- 首先调用
Cola.drink(),但因为你已经用mockStatic(Cola.class)把Cola静态mock了,这个调用会被PowerMock拦截,标记为“需要存根的方法” - 然后调用
thenReturn(),给这个被拦截的方法绑定返回值,整个流程是完整的,PowerMock能识别出这是一个完整的存根操作。
2. doReturn("Drinking").when(Cola.drink()) 为什么报错?
这个写法是Mockito的**“存根后调用”语法,原本是为了解决一些特殊场景(比如方法返回void、避免真实方法调用),但针对静态方法时,语法完全不一样**!
- 你现在的写法里,
when()的参数是Cola.drink()的调用结果,而不是“静态类的mock标记” - PowerMock看到的是:你先调用了
doReturn(),然后调用了Cola.drink()(虽然被mock,但此时PowerMock不知道你是要存根这个方法,反而以为你是在存根过程中又执行了一个真实的mock方法调用,导致存根流程不完整) - 正确的静态方法
doReturn()写法应该是:doReturn().when(Class.class),然后再跟方法调用,而不是把方法调用放进when()里!
正确的doReturn()静态方法存根写法
把你的代码改成下面这样就不会报错了:
PowerMockito.doReturn("Drinking") .when(Cola.class); // 这里传静态类本身,不是方法调用 Cola.drink(); // 这里才是要存根的方法调用
总结一下
针对PowerMockito静态方法的存根,两种写法的正确格式:
- 常规写法(推荐):
PowerMockito.when(Class.staticMethod()).thenReturn(xxx) doReturn写法(特殊场景用):PowerMockito.doReturn(xxx).when(Class.class); Class.staticMethod();
别搞混参数就行,后者的when()里必须传类对象,不能传方法调用结果!
内容的提问来源于stack exchange,提问作者am10
相关产品推荐
相关产品推荐

