当前位置:   article > 正文

PowerMock 私有/公共方法和静态方法对doReturn..when 和 when.thenReturn的不同表现_powermockito.doreturn

powermockito.doreturn

背景:

今天使用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";
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
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";
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

其次是我们使用来测试的代码:

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"));
    }


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

对于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)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

由于对于mock私有和公共方法来说,when.doReturn会使用mock的参数实际调用被mock方法,虽然对于静态方法来说不会这样,但是为了统一,还是推荐mock方法是统一使用doReturn…when的方式来mock数据

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/274471
推荐阅读
相关标签
  

闽ICP备14008679号