簡體   English   中英

如何設計可用於模擬的私有/最終方法?

[英]How to design a private/final method available for mocking?

這是我必須測試的類:

public class Downloader {
  public String download(String uri) {
    HttpClient client = this.getHttpClient();
    client.setURI(uri);
    return client.get();
  }
  private HttpClient getHttpClient() {
    HttpClient client = new HttpClient();
    // + some config
    return client;
  }
}

很簡單。 現在我想在getHttpClient()拋出異常時測試它的行為。 但是,我無法模仿這種方法,因為它是private 這種情況下的常見做法是什么?

我會使HTTPClient成為構建時(通過接口)設置的類的字段。 然后,您可以創建一個模擬HTTPClient,如果您願意,可以在測試期間拋出異常,例如:

public class Downloader {
  private IHTTPClient client;

  public Downloader(IHTTPClient client) {
    this.client = client;
  }

  public String download(String uri) { 
    this.initialiseHttpClient(); 
    client.setURI(uri); 
    return client.get(); 
  } 

  private HttpClient initialiseHttpClient() { 
    // + some config 
  } 
}

然后使用生產代碼中的真實HTTPClient和測試代碼中的Mock調用構造函數。 您可能需要為實際代碼創建HTTPClient的包裝器。

如果您正在嘗試測試私有方法,我認為有些不太對勁。

你應該根據合同測試你的課程。 私有方法依賴於實現,因此(從某種意義上說)它們的作用並不重要。 您應該檢查您的公共方法在功能和非功能方案中是否按預期工作,並將其反映為客戶端(在本例中為您的測試類)。

可能需要將某些功能替換為類以用於測試目的(例如,在破壞的JDBC連接中替換等)。在該場景中,我將研究模擬和依賴注入。

它確實聽起來有點俗氣,但我通常會像這樣公開制作方法並添加明顯的javadocs說“這種方法僅公開用於測試”。

您還可以通過在同一個包中使用xunit / mock等來使用僅包訪問。

我傾向於使用像這樣的簡單解決方案,而不是像AOP風格的代碼注入那樣更復雜和難以調試的技術。

您可以使getHttpClient()受到保護並在測試中將其子類化以返回您想要的內容,因此您在測試中會有類似的內容:

public class TestableDownloader extends Downloader {

  protected HttpClient getHttpClient() {
    throw new Exception();
  }
}

這不是理想的,你最好有一個不同的設計,不要求你測試私有方法(可能使用依賴注入來提供工廠或其他東西)。

私有方法不應該進行單元測試。 您只應該對公共方法進行單元測試。 如何在內部組織公共方法與單元測試無關。 單位不等於方法。 它等於可能使用多種方法完成其工作的行為。

模擬也是一件無用的事情。 如果你必須模擬一些東西,你的方法實際上是集成函數。 你的代碼需要重構才能使它只做一件事,然后一個包裝器方法調用它和被模擬的對象來集成它。

單元測試聽起來像你應該做的事情,但實際上是浪費你最好在編寫應用程序時使用。 單元測試不能保證更好的代碼質量,也許它會使它變得更糟,因為你沒有在你的真實代碼上花費足夠的時間。

暫無
暫無

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

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