Powermock 扩展于EasyMock和Mockito,而Mockito相对于EasyMock的优点其中一个是异常更清晰易懂。
现在用的是基于Mockito的Powermock,它可以mock静态方法,mock构造函数,mock void方法,mock部分方法,mock私有方法等。以下是如果使用基于Mockito的Powermock版本。
1.导入包
其中 <powermock.version>1.6.3</powermock.version>
<dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-easymock</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency>
假设我们需要测试下面的Hello类
class Hi { public void mockParentMethod() { System.out.println("mockSuperMethod Hi"); } } class Hello extends Hi { private Kitty kitty; public Hello() {} public void mockParentMethod() { super.mockParentMethod(); System.out.println("mockParentMethod Hello"); } public void mockNonStaticMethod() { String name = kitty.getName(); System.out.println("mockNonStaticMethod" + name); } public void mockStaticMethod() { String name = Kitty.getName2(); System.out.println("mockStaticMethod" + name); } public void partialMock() { _partialMock(); System.out.println("partialMock"); } private void _partialMock() { System.out.println("method3"); } public void mockVoidMethod() { kitty.say3(); System.out.println("partialMock"); } public Kitty getKitty() { return kitty; } public void setKitty(Kitty kitty) { this.kitty = kitty; } } class Kitty { public String getName() { return "Kitty"; } public static String getName2() { return "Kitty"; } public void say3() { System.out.println("say3"); } }
2. 导入声明
测试类时,要导入以下声明:
@RunWith(PowerMockRunner.class) public class HelloTest { }
3. 测试方法
3.1 mock 非静态方法
@Test public void testMockNonStaticMethod() { Hello hello = new Hello(); Kitty kitty = PowerMockito.mock(Kitty.class); hello.setKitty(kitty); PowerMockito.when(kitty.getName()).thenReturn("test"); hello.mockNonStaticMethod(); }
3.2 mock 静态方法
首先需要PrepareForTest导入静态方法的类
@RunWith(PowerMockRunner.class) @PrepareForTest({Kitty.class}) class HelloTest { @Test public void testMockStaticMethod() { Hello hello = new Hello(); PowerMockito.mockStatic(Kitty.class); PowerMockito.when(Kitty.getName2()).thenReturn("test"); hello.mockStaticMethod(); } }
3.3 partial mock (mock 部分方法)
如果只想mock一个类里面的个别方法,可以使用spy方法
@RunWith(PowerMockRunner.class) @PrepareForTest({Hello.class}) public class HelloTest { @Test public void testPartialMock() { Hello hello = PowerMockito.spy(new Hello()); try { PowerMockito.doReturn("test").when(hello, MemberMatcher.method(Hello.class, "_partialMock")).withNoArguments(); } catch (Exception e) { e.printStackTrace(); } hello.partialMock(); } }
3.4 mock void 方法
@Test public void testMockVoidMethod() { Hello hello = new Hello(); Kitty kitty = PowerMockito.mock(Kitty.class); hello.setKitty(kitty); PowerMockito.doNothing().when(kitty).say3(); hello.mockVoidMethod(); }
3.5 mock parent method (父类方法)
使用PowerMockito.suppress()方法
@Test public void testMockParentMethod() { Hello hello = new Hello(); PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(Hi.class)); hello.testMockParentMethod(); }
不过这个版本好像有个bug,如果用了spy mock 子类,当子类方法里面调了父类的两次(或以上)相同或者不相同的方法时,测试子类的方法会报StackOverflowError异常,如下面的子类方法:
public void mockParentMethod() { super.mockParentMethod(); //一次 System.out.println("mockParentMethod Hello"); super.mockParentMethod(); //两次 }
@Test public void testMockParentMethod() { Hello hello = PowerMockito.spy(new Hello()); PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(Hi.class)); hello.testMockParentMethod(); // throw StackOverflowError exception }
3.6 测试私有方法
格式: PowerMockito.verifyPrivate(objectOrClassToInvoke).invoke("methodToBeTest", parms);
public void testPrivateMethod() { Hello hello = new Hello(); PowerMockito.verifyPrivate(hello).invoke("_partialMock"); }
或者使用 WhiteBox.invokeMethod() 方法。
3.6 mock构造函数
使用 PowerMockito.whenNew() 方法
Hello hello = PowerMockito.mock(Hello.class) PowerMockito.whenNew(Hello.class).thenReturn(hello);
相关链接
powermock官网:https://github.com/jayway/powermock