使用指定版本Mockito/PowerMock仅Mock Java类中被调用的构造函数
Mock Foo类中被调用的构造函数(JUnit 4.12 + Mockito 1.10.19 + PowerMock)
刚好处理过类似的需求,结合你指定的测试框架版本,我们可以用PowerMock的构造函数拦截能力来实现目标,完全不需要修改被测的Foo类代码,具体步骤如下:
第一步:配置测试类的注解
首先得给测试类加上PowerMock的运行器和准备注解,这样PowerMock才能修改Foo类的字节码,实现构造函数的拦截:
@RunWith(PowerMockRunner.class) @PrepareForTest(Foo.class) // 必须指定要Mock构造的目标类 public class FooTest { // 测试用例写在这里 }
第二步:编写测试逻辑,Mock目标构造函数
假设你要Mock的是Foo(Connection, File)这个构造(因为Foo(Connection)会主动调用它),我们可以拦截这个构造的调用,返回一个Mock实例,避免执行真实的构造逻辑:
@Test public void testConstructorInvocation() throws Exception { // 先创建Connection的Mock对象,作为构造入参 Connection mockConn = Mockito.mock(Connection.class); // 定义我们要返回的Foo Mock实例 Foo mockFooInstance = Mockito.mock(Foo.class); // 用PowerMock拦截Foo(Connection, File)构造的调用 PowerMockito.whenNew(Foo.class) .withArguments(Mockito.any(Connection.class), Mockito.any(File.class)) .thenReturn(mockFooInstance); // 调用被测的构造函数Foo(Connection) Foo actualInstance = new Foo(mockConn); // 验证:确认被调用的构造函数确实被拦截触发 PowerMockito.verifyNew(Foo.class).withArguments(mockConn, Mockito.any(File.class)); // 验证返回的实例是我们预先定义的Mock对象 Assert.assertEquals(mockFooInstance, actualInstance); }
关键细节说明
@PrepareForTest(Foo.class):这一步必不可少,PowerMock需要通过这个注解来准备目标类,实现构造函数的拦截逻辑。PowerMockito.whenNew():这个方法是核心,用来指定要拦截的构造函数,通过withArguments()匹配参数(可以用any()模糊匹配,也可以用eq()做精确匹配),然后用thenReturn()返回你想要的实例。- 如果只是想避免真实构造的副作用,不需要返回Mock实例,也可以返回一个部分Mock的Foo对象,甚至直接返回
null(根据你的测试场景灵活调整)。
版本兼容性提醒
你使用的powermock-mockito-1.7.1和mockito-1.10.19是兼容的,powermock-1.7.4也能和这个版本组合正常工作,不用担心版本冲突问题。
内容的提问来源于stack exchange,提问作者user1759789
相关产品推荐
相关产品推荐

