4 回答

TA貢獻1866條經驗 獲得超5個贊
您在這里遇到的問題是您的類與其他類的特定實現緊密耦合,因此您的“單元”被迫一起測試所有這些類的行為。
避免這種情況的典型方法是使用依賴注入,使您的類與接口而不是特定類耦合。然后您可以模擬注入的接口以對單個類的行為進行單元測試。
public class AImpl {
public B b;
public AImpl(B b) {
this.b = b;
}
}
public interface B {
// methods
}
public class BImpl implements B {
public C c;
public BImpl (C c) {
this.c = c;
}
}
當您創建AImpl生產代碼時,您現在必須為其提供特定的C實現。您可以這樣做new AImpl(new BImpl(new CImpl)),也可以使用像 Spring 這樣的依賴注入框架來為您計算出所有這些細節。
B當您進行單元測試時,您可以創建一個模擬或存根以具有您希望為該特定測試展示的行為,并將該存根傳遞給構造函數: new AImpl(myMockedB)。

TA貢獻1859條經驗 獲得超6個贊
B
您不應該在類中創建實例A
- 相反,您應該B
在創建時提供實例A
- 它稱為Inversion of Control。流行的方法是使用依賴注入,例如使用 Spring 框架。
然后一切都變得簡單 - 當您的類需要讀取帶有類的文件時FileReader
,為了測試您可以創建一個“假”實現,例如當您調用時FileReader.readFile()
,您的假實現將簡單地返回硬編碼字符串或流,具體取決于您想要什么。
這個概念真的很大,想象一下當你FileReader
實際上是一個DatabaseReader
or ExternalServiceCaller
。不是在單元測試中測試真實的數據庫(祝你好運),而是創建一個FakeDatabaseReader
在常規 Java 上運行的數據庫HashMap
,一切都很容易測試。
或者當您的代碼處理時間/日期時,想象一個功能只在29th February
- 您可以等待 4 年來測試它,或者為Clock
您的測試提供一個設置為特定日期的對象。該類Clock
具有提供各種替代時鐘的靜態方法,以提供固定時刻、調整到未來或過去的時刻,或具有改變節奏的時鐘。

TA貢獻1816條經驗 獲得超6個贊
首先,由于您不能注入 B 類,因此所有此類都不是為了進行溫和測試而設計的,請注意,由于您將任何新內容添加到類中,這與對實例進行硬編碼非常相似。
適當的方式應該是
public class A {
public B b;
public A(B b) {
this.b = b;
}
}
請注意,您可以通過這種方式實例化類
A a = new A(b);
這樣,b 可以是模擬或虛擬或存根或任何用于測試目的的對象。如果您面臨遺留代碼,您應該重構它以使其能夠被測試。如果這是您的設計,您應該盡快重構以使其可測試。
控制反轉和依賴注入應該有助于歸檔你想做的事情。

TA貢獻1848條經驗 獲得超2個贊
不是我知道的,你會處理這些外部因素,或者在 A、B 或 C 類本身的開發過程中確保在測試過程中不會出現此類問題。
但是,如果您無法控制 A、B 或 C 類源,那么我認為您被卡住了!
添加回答
舉報