[英]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.