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