概述:
PowerMockito擅长mock静态类/静态方法/私有方法/构造器
1. 当给spy的类设桩时,最好使用doReturn / doThrow / doNothing(只适应于返回void的方法)等,使用thenReturn/thenThrow可能会产生一些错误,
参考示例代码:testStub4SpyClass;
2. 当给静态方法设桩时,使用thenReturn/ thenThrow, 参考示例代码:verifyStaticMethod1;
3. 如果想验证测试类的private方法, 需要spy测试类,示例代码参考:verifyPrivateMethod;
4. Mockito&PowerMockito无法mock final类和方法;
5. 当使用PowerMockito时, 如果when在末尾, 方法的参数必须是实例,不能是方法调用(如method1(), 当用方法调用时,
mockito会认为是开始stub),当是方法调用的时候会报错:Unfinished-StubbingException; when在thenReturn前没有问题,
参考代码:verifyTheStubbingOfWhen;
6. 如果想验证构造器,必须在方法执行前为类声明whenNew, 参考代码:verifyConstructor;
7. @PrepareForTest()的参数为Class[], 或String[], 例如:@PreapareForTest(fullyQualifiedNames={"xxx", "xxxxx"}, 源码如下:
public @interface PrepareForTest
{
public abstract Class>[] value();
public abstract String[] fullyQualifiedNames();
}
示例代码:
package com.ray.mockito_demo1;
import static org.mockito.Mockito.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
// 声明需要测试静态方法/私有方法的类, 可以声明多个,用逗号隔开
@PrepareForTest({ ClassA.class })
public class PowerMockitoDemo3 {
// /$ begin test ClassA
@InjectMocks
private ClassA classA;
@Test
public void testStub4SpyClass() throws Exception {
classA = PowerMockito.spy(classA);
String task = "跑步";
// PowerMockito.when(classA, "method2", task).thenReturn("。。。。");
PowerMockito.doReturn("。。。。").when(classA, "method2", task);
classA.invokeMethod2(task);
PowerMockito.verifyPrivate(classA).invoke("method2", task);
}
@Test
public void verifyTheStubbingOfWhen() throws Exception {
User u1 = mock(User.class);
when(u1.getName()).thenReturn("张三");
classA = PowerMockito.spy(classA);
// 抛出异常UnfinishedStubbingException
PowerMockito.doReturn("。。。。").when(classA, "method2", u1.getName());
//正确的方式
// PowerMockito.doReturn("。。。。").when(classA, "method2", "张三");
//或者 PowerMockito.when(classA, "method2", u1.getName()).thenReturn("。。。。");
classA.invokeMethod2(u1.getName());
PowerMockito.verifyPrivate(classA).invoke("method2", u1.getName());
}
@Test
public void verifyStaticMethod1() throws Exception {
PowerMockito.mockStatic(ClassA.class);
PowerMockito.spy(ClassA.class);
PowerMockito.doReturn("hahaha").when(ClassA.class, "staticMethod1");
ClassA.invokeStaticMethod1();
PowerMockito.verifyStatic();
ClassA.staticMethod1();
}
@Test
public void verifyPrivateMethod() throws Exception {
// 如果不将PowerMockito.spy(classA)赋值给classA, mock将不会生效
classA = PowerMockito.spy(classA);
classA.invokeMethod1();
PowerMockito.verifyPrivate(classA).invoke("method1");
}
@Test
public void verifyConstructor() throws Exception{
User u1 = mock(User.class);
when(u1.getName()).thenReturn("李四");
//如果没有设置whenNew, 将会报错IllegalStateException...
//Note that only expected object creations(e.g. those using whenNew(..)) can be verified
PowerMockito.whenNew(User.class).withNoArguments().thenReturn(u1);
classA.invokeMethod3();
PowerMockito.verifyNew(User.class).withNoArguments();
}
}
class ClassA {
public static void invokeStaticMethod1() {
System.out.println(staticMethod1());
}
public static String staticMethod1() {
return "test static method1.";
}
public void invokeMethod1() {
method1();
}
public void invokeMethod2(String param) {
System.out.println(method2(param));
}
public void invokeMethod3(){
User user = new User();
user.setName("张三");
method3(user);
}
private void method3(User user){
System.out.println(String.format("Welcome, %s", user.getName()));
}
private void method1() {
System.out.println("method1 executed.");
}
private String method2(String task) {
return String.format("%s executed.", task);
}
}
class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
相关jar包:
mvn仓库:http://mvnrepository.com/
org.mockito
mockito-all
1.9.5
test
org.powermock
powermock-module-junit4
1.5.5
org.powermock
powermock-api-mockito
1.5.5