如何Mock Final Class构造方法?示例代码执行报错求助
解决Final类构造方法Mock抛出RuntimeException的问题
我明白你现在的困扰:想要Mock一个Final类的构造方法,但原构造方法里的RuntimeException还是会被触发,导致测试失败。这是因为PowerMock拦截构造调用的机制需要同时处理创建Final类实例的调用者类,而不仅仅是Final类本身,咱们一步步来解决这个问题。
问题根源
你的FooClass里直接执行了new FinalClass("arg1"),PowerMock要拦截这个构造调用,需要修改FooClass的字节码来替换掉原有的new操作。但你之前只给FinalClass加了@PrepareForTest注解,没有包含FooClass,所以PowerMock没法拦截这个调用,原构造方法还是会执行,自然抛出了异常。
修正后的完整测试代码
下面是调整后的测试类,关键改动我已经标出来了:
@RunWith(PowerMockRunner.class) @PowerMockRunnerDelegate(MockitoJUnitRunner.class) @PowerMockIgnore({"javax.management.*", "org.apache.http.conn.ssl.*", "com.amazonaws.http.conn.ssl.*", "javax.net.ssl.*"}) // 重点:把创建FinalClass实例的FooClass也加入到PrepareForTest中 @PrepareForTest({FinalClass.class, FooClass.class}) public class FooTest { @InjectMocks FooClass fooClass; @Before public void before() { // 这里可以去掉MockitoAnnotations.initMocks,因为@RunWith已经自动处理了Mock初始化 // MockitoAnnotations.initMocks(this); } @Test public void finalClass() throws Exception { // 创建FinalClass的Mock实例 FinalClass finalClassMock = PowerMockito.mock(FinalClass.class); // 拦截所有FinalClass的构造调用,返回我们的Mock实例 PowerMockito.whenNew(FinalClass.class).withAnyArguments().thenReturn(finalClassMock); // 执行待测试的方法 fooClass.someMethod(); // 可选:验证printMsg方法是否被调用,确保逻辑正常走到这一步 Mockito.verify(finalClassMock).printMsg(); } }
额外注意事项
- 版本兼容性:确保PowerMock和Mockito的版本匹配,比如PowerMock 2.0+对应Mockito 2.x/3.x版本,版本不匹配可能会导致各种奇怪的问题。
- 精确参数匹配:如果需要只拦截特定参数的构造调用,可以把
withAnyArguments()换成withArguments("arg1"),这样只会匹配传入"arg1"的构造方法。 - 冗余代码清理:
@RunWith(PowerMockRunner.class)结合@InjectMocks已经会自动初始化Mock对象,所以MockitoAnnotations.initMocks(this)可以去掉,避免重复初始化。
这样调整后,PowerMock就能正确拦截FooClass里的new FinalClass("arg1")调用,返回你创建的Mock实例,不会再触发原构造方法的RuntimeException了。
内容的提问来源于stack exchange,提问作者ramazankul
相关产品推荐
相关产品推荐

