簡體   English   中英

使用power mockito來抑制私有靜態方法

[英]Using power mockito to suppress private static method

我舉了一個代碼來舉例說明問題

public class SiteTranslator {
   Integer id;
   //Other fields
}

public class SiteUtil {

  private static SiteTranslator siteTranslator = getSiteTranslator();

  private static SiteTranslator getSiteTranslator()
  {
    SiteTranslator siteTranslator;
    //Logic involving network call
    return siteTranslator;
  }

  private static String getEnvironment()
  {
    String env = "";
    //Logic
    return env;
  }

  public static int getParent(int siteId)
  {
    int parentId = 0;
    //Logic using siteTranslator from getSiteTranslator()
    return parentId;
  }
}


public class SiteUtilTest {
  @Test
  public void test1()
  {
    try
    {
        PowerMockito.suppress(SiteUtil.class.getMethod("getSiteTranslator")); 
        BDDMockito.given(SiteUtil.getParent(1)).willReturn(6);
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
  }
}

我們從getSiteTranslator()方法獲得的SiteTranslator對象由我的公共函數getParent()使用。 由於getSiteTranslator()需要網絡調用,因此需要對其進行抑制。 但是我得到以下錯誤

java.lang.NoSuchMethodException: SiteUtil.getSiteTranslator()

我相信問題是因為我試圖模擬私有靜態函數。 但是我無法將其改為公開。 有沒有辦法在當前狀態下模擬代碼。

其實,你並不需要Powermockito達到你所需要的。

目前,您認為需要Powermockito來抑制私有靜態方法,但這絕對不是可行的方法。

相反,您應該重構代碼以使其更容易測試:

  • 刪除static限定符
  • 使用依賴注入

在這樣的重構之后,你最終得到類似的東西(不需要嘲笑!):

public class SiteUtil {
    private SiteTranslator siteTranslator;

    public SiteUtil(SiteTranslator siteTranslator) {
        this.siteTranslator = siteTranslator;
    }

    public int getParent(int siteId) {
        int parentId = 0;
        // Logic using siteTranslator
        return parentId;
    }

    ...
}

現在你可以這樣測試它:

public class SiteUtilSpec {
    private final SiteTranslator defaultTranslator = new DummySiteTranslator();

    @Test
    public void itShouldReturnTheSixthSiteWhenWeProvideTheFirstParent() {
        SiteUtil site = new SiteUtil(defaultTranslator);

        int parentId = site.getParent(1);

        assertEquals(6, parentId);
    }
}

DummySiteTranslator是一個假對象(也許它嵌入了一堆硬編碼的翻譯,可用於測試)但關鍵是這個對象永遠不會進行任何網絡調用! 使其安全,快速(非常適合測試)。

“Spotted”的答案已經指出了它,因為核心問題是:你完全沒有理由創建了難以測試的代碼。

使用這樣的內部靜態調用只會使您的程序難以測試; 並且驚喜:它也使得難以維護,增強和重用。 您需要轉向Powermock的事實通常只是表明您的生產代碼不好 現在,您可以選擇使用PowerMock來“修復”該問題 ; 或者通過更改生產代碼來解決問題 - 以示例代碼的方式解決問題是一種不好的做法!

所以,另一個真正的教訓是:你想花一些時間來學習如何編寫沒有這些問題的代碼; 例如,通過觀看那些視頻

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM