我有一個計算某事的代碼,緩存是,如果已經計算,則從緩存中讀取;與此類似:在JUnit測試的情況下檢查類內的調用次數
public class LengthWithCache {
private java.util.Map<String, Integer> lengthPlusOneCache = new java.util.HashMap<String, Integer>();
public int getLenghtPlusOne(String string) {
Integer cachedStringLenghtPlusOne = lengthPlusOneCache.get(string);
if (cachedStringLenghtPlusOne != null) {
return cachedStringLenghtPlusOne;
}
int stringLenghtPlusOne = determineLengthPlusOne(string);
lengthPlusOneCache.put(string, new Integer(stringLenghtPlusOne));
return stringLenghtPlusOne;
}
protected int determineLengthPlusOne(String string) {
return string.length() + 1;
}
}
我希望測試功能determineLengthPlusOne
已被調用的次數足夠多,這樣的:
public class LengthWithCacheTest {
@Test
public void testGetLenghtPlusOne() {
LengthWithCache lengthWithCache = new LengthWithCache();
assertEquals(6, lengthWithCache.getLenghtPlusOne("apple"));
// here check that determineLengthPlusOne has been called once
assertEquals(6, lengthWithCache.getLenghtPlusOne("apple"));
// here check that determineLengthPlusOne has not been called
}
}
嘲諷類LengthWithCache
似乎不是一個很好的選擇,因爲我想測試他們的功能。 (根據我的理解,我們嘲笑被測試的類使用的類,而不是被測試的類本身。)哪一個是最優雅的解決方案?
我的第一個想法是創建另一個類LengthPlusOneDeterminer
包含函數determineLengthPlusOne
,添加它傳遞給函數getLenghtPlusOne
作爲參數,並在單元測試的情況下模擬LengthPlusOneDeterminer
,但似乎有點奇怪,因爲它具有對工作造成不必要的影響代碼(類LengthWithCache
的真實客戶端)。
基本上我使用的是Mockito,但無論是模擬框架(或其他解決方案),歡迎!謝謝!
我認爲與嘲弄一個孤立的單元測試來測試這是不是最好的ID EA。相反,編寫一個測試,只驗證被測試類的*外部可觀察行爲*。內部使用緩存最終只是一個旨在提高性能的實現細節。也許可以寫一個測試來檢測這樣的性能改進(使用'System.nanoTime()');如果沒有,那麼緩存可能無用,可以刪除。 –
謝謝你的評論。緩存機制在實踐中變得有用。 –
爲什麼對這個問題倒下了?客觀地說,這是一個非常有趣的混合設計和單元測試主題。它值得更好。 – davidxxx