Powermockito 針對方法中new 對象的模擬,以及屬性中new 對象的模擬


PowerMocker 是一個功能逆天的mock 工具。

一,Powermockito 針對方法中new 對象的模擬

// 如何才能mock掉 WeChatConfigUtil 這個類,讓 weChatConfigUtil.getMainApploginSwitch();這個方法返回你想要的結果
public void testA(){
    WeChatConfigUtil weChatConfigUtil = new WeChatConfigUtil();
    weChatConfigUtil.getMainAppLoginSwitch();
  }

 

針對上述情況

package com.ppdai.wechat.sub.business.msgsub;

import com.ppdai.wechat.sub.util.WeChatConfigUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

/**
 * Created by huxuhong on 2020/7/2.
 */
//重點,要幫要mock的類(此例為weChatConfigUtil 所在的類TestC,要放到PrepareForTest中即可)
@PrepareForTest(
        {   TestB.TestC.class
        })
@RunWith(PowerMockRunner.class)
public class TestB {
    public TestB(){

    }
    class TestC{
        public void testA(){
            WeChatConfigUtil weChatConfigUtil = new WeChatConfigUtil();
            Boolean flag = weChatConfigUtil.getMainAppLoginSwitch();
            System.out.println("mock結果"+flag);
        }
    }

    @Test
    public void testTestC(){
        TestC testC = new TestC();
        WeChatConfigUtil weChatConfigUtil = PowerMockito.mock(WeChatConfigUtil.class);
        try {
            PowerMockito.whenNew(WeChatConfigUtil.class).withAnyArguments().thenReturn(weChatConfigUtil);
            PowerMockito.doReturn(Boolean.TRUE).when(weChatConfigUtil).getMainAppLoginSwitch();
            testC.testA();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

運行結果

 

二,如何解決屬性中new 對象的模擬

 

public class TestB {
    public TestB(){

    }
    class TestC{
//如何mock掉屬性中new 對象(此例為WechatConfigUtil weChatConfigUtil = new WechatConfigUtil,讓 weChatConfigUtil.getUserInfoApiUrl 能獲取到指定的值) WeChatConfigUtil weChatConfigUtil = new WeChatConfigUtil(); public void testA(){ String t = weChatConfigUtil.getUserInfoApiUrl(); System.out.println("mock結果"+t); } }

  

針對上述情況

public class TestB {
    public TestB(){

    }
    class TestC{
//如果熟悉修飾為pubilc final static WechatConfigUtil,那么就需要和上面的例子一樣要配置@PrepareForTest WeChatConfigUtil weChatConfigUtil = new WeChatConfigUtil(); public void testA(){ String t = weChatConfigUtil.getUserInfoApiUrl(); System.out.println("mock結果"+t); } } @Test public void testTestC(){ TestC testC = new TestC(); WeChatConfigUtil weChatConfigUtil = PowerMockito.mock(WeChatConfigUtil.class); try { Field weChatConfigUtilField = testC.getClass().getDeclaredField("weChatConfigUtil"); weChatConfigUtilField.setAccessible(Boolean.TRUE); weChatConfigUtilField.set(testC,weChatConfigUtil); PowerMockito.doReturn("testpc").when(weChatConfigUtil).getUserInfoApiUrl(); testC.testA(); } catch (Exception e) { e.printStackTrace(); } } }

  運行結果

 

 

 

三,引入Powermock的時候注意和mockito的版本匹配問題

  Powermock 使用過程中遇到的坑

   ①,使用Powermock mock 靜態方法時,提示下面錯誤

        org.mockito.exceptions.misusing.NotAMockException: Argument should be a mock, but is: class java.lang.Class

         處理方式:版本問題,修改為  mockito 2.25.0,powermock 2.0.2,

        issue https://github.com/powermock/powermock/issues/992#ref-commit-3479902

   

mockito 2.25.0和powermock 2.0.2


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM