赞
踩
今天使用powermock的时候同事说被mock的私有/公共方法一直报空指针异常,但是mock静态类并没有异常,觉得很奇怪,本文就来讲下powermock私有/公共方法和静态方法对于doReturn…when 和 when.thenReturn的不同表现,以及使用时的注意事项
首先看下用来mock测试的私有方法和静态方法类,如下图所示:
public class MyPrivateMethod {
private String myPrivateFunc(Integer num){
String result = "private:" + num.toString();
return result;
}
public String myShow(Integer num){
return myPrivateFunc(num) + "_xxxxx";
}
}
public class MyStaticMethod {
public static String myStaticFunc(Long num) {
String result = "static:" + num.toString();
return result;
}
public String myDisplay(Long num) {
return myStaticFunc(num) + "_yyyyy";
}
}
其次是我们使用来测试的代码:
import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) @PowerMockIgnore({"javax.management.*", "javax.net.ssl.*"}) @PrepareForTest({MyPrivateMethod.class, MyStaticMethod.class}) public class PowerMockTest { /** * 对于私有和共有方法的mock 1. when().thenReturn的方式会使用mock的参数调用被mock的方法,产生副作用,比如这里的空指针异常 */ @Test public void testPrivate0() throws Exception { MyPrivateMethod inst = PowerMockito.spy(new MyPrivateMethod()); // 这种方式会使用Mockito.any()也就是null对象调用myPrivateFunc函数,此时就会产生空指针异常 PowerMockito.when(inst, "myPrivateFunc", Mockito.any()).thenReturn("mockPrivateResult"); Integer num = 100; String ret = inst.myShow(num); Assert.assertTrue(ret.equals("mockPrivateResult_xxxxx")); } /** * 对于私有和共有方法的mock 1. doReturn().when不会产生额外的副作用,这其实才是真正我们想要的. */ @Test public void testPrivate1() throws Exception { MyPrivateMethod inst = PowerMockito.spy(new MyPrivateMethod()); // 这种方式不会实际调用myPrivateFunc方法,所以不会产生异常 PowerMockito.doReturn("mockPrivateResult").when(inst, "myPrivateFunc", Mockito.any()); Integer num = 100; String ret = inst.myShow(num); Assert.assertTrue(ret.equals("mockPrivateResult_xxxxx")); } /** * 静态方法的mock * 1.不论是使用when().thenReturn的方式还是doReturn.when的方式都不会产生副作用 * */ @Test public void testStatic() throws Exception { MyStaticMethod inst = PowerMockito.spy(new MyStaticMethod()); PowerMockito.mockStatic(MyStaticMethod.class); PowerMockito.when(MyStaticMethod.myStaticFunc(Mockito.any())).thenReturn("myStaticFunc"); // PowerMockito.doReturn("myStaticFunc").when(MyStaticMethod.class, "myStaticFunc", Mockito.any()); Long num = 1000L; String ret = inst.myDisplay(num); Assert.assertTrue(ret.equals("myStaticFunc_yyyyy")); } }
对于mock私有和公共方法来说异常如下:
java.lang.NullPointerException
at org.example.pmock.MyPrivateMethod.myPrivateFunc(MyPrivateMethod.java:7)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.example.pmock.PowerMockTest.testPrivate0(PowerMockTest.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
由于对于mock私有和公共方法来说,when.doReturn会使用mock的参数实际调用被mock方法,虽然对于静态方法来说不会这样,但是为了统一,还是推荐mock方法是统一使用doReturn…when的方式来mock数据
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。