powermock框架(建议不用,mockito已经支持mock静态方法 )

2022-07-19 10:27:21

一、为什么要用powermock?

  • 能对private/static/final等方法mock
  • 能mock方法中 ”new出来“的对象“

二、powermock的使用

1、 maven依赖

<dependency><groupId>org.powermock</groupId><artifactId>powermock-module-junit4</artifactId><version>2.0.0</version><scope>test</scope></dependency><dependency><groupId>org.powermock</groupId><artifactId>powermock-api-mockito2</artifactId><version>2.0.0</version><scope>test</scope></dependency>

2、springboot基础配置(测试基类)

@PreparwForeTest({被mock的静态方法})@RunWith(PowerMockRunner.class)@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)@PowerMockIgnore({"javax.net.ssl.*","javax.management.*","javax.crypto.*"})@SpringBootTestpublicclassBasePowerMock{}

3、mock对象

1)@Mock和@MockBean

  • @Mock(需要MockAnotation.init(this)初始化: 完全mock一个对象
    等于Mockito.mock(Object.class)
  • @MockBean:mock对象替换Spring容器中的同样类型的bean

2)@Spy和@SpyBean

  • @Spy: 不mock,则与普通对象一样
  • @SpyBean: 不mock,则与Spring中的bean一样

4、stub

1)mock目标对象的public、private、final、static方法:

目标对象

publicclassMyThread{publicvoiddoMain(){
        System.out.println(doPublic());
        System.out.println(doPrivate());
        System.out.println(doFinal());
        System.out.println(doStatic());}public StringdoPublic(){return"this is real public";}publicstatic StringdoStatic(){return"this is real private";}private StringdoPrivate(){return"this is real private";}publicfinal StringdoFinal(){return"this is real final";}}

mock方法

@RunWith(PowerMockRunner.class)@PrepareForTest({MyThread.class,Thread.class})publicclassMyThreadTest{@TestpublicvoidtestMock()throws Exception{
        MyThread  myThread= PowerMockito.spy(newMyThread());

        PowerMockito.doReturn("this is mock public").when(myThread,"doPublic");
        PowerMockito.doReturn("this is mock private").when(myThread,"doPrivate");
        PowerMockito.doReturn("this is mock final").when(myThread,"doFinal");//mock 静态方法
        PowerMockito.mockStatic(MyThread.class);
        PowerMockito.doReturn("this is mock static").when(MyThread.class,"doStatic");

        myThread.doMain();}}

结果:
在这里插入图片描述

注意点:

  • mock静态方法,mock的是目标.class

2) mock目标对象中的方法中”new出来的对象“:

目标类

publicclassMockOutClass{publicvoiddoMain(){
        MyThread myThread=newMyThread();
        myThread.doMain();}}

mock类

@RunWith(PowerMockRunner.class)@PrepareForTest({MockOutClass.class,MyThread.class})publicclassMockOutClassTest{@TestpublicvoidtestMock()throws Exception{
        MockOutClass mockOutClass= PowerMockito.spy(newMockOutClass());//mock new
        MyThread myThread= PowerMockito.spy(newMyThread());
        PowerMockito.whenNew(MyThread.class).withAnyArguments().thenReturn(myThread);//mock method
        PowerMockito.doReturn("this is mockOut public").when(myThread).doPublic();
        PowerMockito.doReturn("this is mock private").when(myThread,"doPrivate");
        PowerMockito.doReturn("this is mock final").when(myThread,"doFinal");//mock 静态方法
        PowerMockito.mockStatic(MyThread.class);
        PowerMockito.doReturn("this is mock static").when(MyThread.class,"doStatic");

        mockOutClass.doMain();}}

4、verify

1) 方法调用次数

 - 默认一次   Mockito.verify(uploadDataToUmpService).uploadTotalCount(Mockito.anyList());
 - 自定义次数:
 			Mockito.verify(uploadDataToUmpService,Mockito》times(2)).uploadTotalCount(Mockito.anyList());

2)断言异常

断言异常

三、powermock原理探究

1.简单原理

PowerMock简单实现原理

  • 当某个测试方法被注解@PrepareForTest标注以后,在运行测试用例时,会创建一个新org.powermock.core.classloader.MockClassLoader实例,然后加载该测试用例使用到的类(系统类除外)。
  • PowerMock会根据你的mock要求,去修改写在注解@PrepareForTest里的class文件(当前测试类会自动加入注解中),以满足特殊的mock需求。例如:去除final方法的final标识,在静态方法的最前面加入自己的虚拟实现等。
  • 如果需要mock的是系统类的final方法和静态方法,PowerMock不会直接修改系统类的class文件,而是修改调用系统类的class文件,以满足mock需求
  • 作者:Java养家
  • 原文链接:https://blog.csdn.net/qq_41930516/article/details/119305887
    更新时间:2022-07-19 10:27:21