1 回答

TA貢獻1799條經驗 獲得超8個贊
像往常一樣,單元測試迫使您考慮類的設計。
首先,您應該注意到您有兩種主要的不同類型的對象。
有些對象是值:它們是不可變的,可以存在于多個副本中,是可比較的(并且hashCode
也有一個)。這是一種易于存儲在數據庫中的對象。如果您對 Kotlin 有所了解,您就會聽說過data classes
: 就是這樣。
其他一些具有實體語義的對象:它們是可變的,比較它們沒有意義,而且通常只有它們的一個副本。它們是做某事的對象。
具有實體語義的對象是您需要在單元測試中模擬的對象,而您不需要模擬值。為了傳遞模擬,這些對象必須作為構造函數的參數注入到類中。
在您的代碼片段中,您在函數中創建了一個對象,該對象似乎具有實體的語義(值什么都沒有finish
),這就是您遇到問題的原因:您無法進行單元測試,因為您無法模擬該實體.
解決方案很簡單:要么在方法中注入對象:
public interface ISomeInterface
{
? ? default Integer callMe(Object someObject)
? ? {
? ? ? ? Integer result = someObject.finish();
? ? ? ? result = result + 1;
? ? ? ? return result;
? ? }
? ? ...
}
或者你在類中注入對象:
public interface ISomeInterface
{
? ? default Integer callMe()
? ? {
? ? ? ? Integer result = finishObject();
? ? ? ? result = result + 1;
? ? ? ? return result;
? ? }
? ? // classes will need an instance of the object to implement this
? ? Integer finishObject();?
? ? ...
}
在這兩種情況下,實現您的接口的類要么負責在調用方法時提供對象本身,要么負責返回方法的值finish。
但請記住:如果您在這些類的方法中創建對象,對它們進行單元測試也會變得困難。使用工廠模式在靜態方法中創建實體對象并將這些對象傳遞給構造函數。
如果遵循這條經驗法則,類和方法的單元測試將變得更容易:當對象具有語義值時,在更高級別創建它(如果可能)并將其作為構造函數或方法的參數main傳遞。
添加回答
舉報