我正在測試一個班級,我需要一段時間才能檢查結果。具體而言,我需要x分鐘才能確定測試是否奏效。我已經讀過,在單元測試中,我們應該測試接口而不是實現,所以我們不應該訪問私有變量,但除了在我的單元測試中進行睡眠之外,我不知道如何在不修改私有變量的情況下進行測試。如何在不訪問私有變量的情況下測試jUnit測試中的時間傳遞?
我的測試設置是這樣的:
@Test
public void testClearSession() {
final int timeout = 1;
final String sessionId = "test";
sessionMgr.setTimeout(timeout);
try {
sessionMgr.createSession(sessionId);
} catch (Exception e) {
e.printStackTrace();
}
DBSession session = sessionMgr.getSession(sessionId);
sessionMgr.clearSessions();
assertNotNull(sessionMgr.getSession(sessionId));
Calendar accessTime = Calendar.getInstance();
accessTime.add(Calendar.MINUTE, - timeout - 1);
session.setAccessTime(accessTime.getTime()); // MODIFY PRIVATE VARIABLE VIA PROTECTED SETTER
sessionMgr.clearSessions();
assertNull(sessionMgr.getSession(sessionId));
}
是否有可能比修改accessTime專用變量中測試該其他(通過創建setAccessTime設定器或反射)在單元測試,或插入sleep ?
EDIT 11月 - 2012
我特別想測試的特定時間段過去之後我SessionManager對象清除會話。我連接的數據庫將在一段固定時間後斷開連接。當我接近該超時時,SessionManager對象將通過在數據庫上調用「最終會話」過程並從其內部列表中刪除會話來清除會話。
SessionManager對象被設計爲在單獨的線程中運行。該代碼我測試看起來像這樣:
public synchronized void clearSessions() {
log.debug("clearSessions()");
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE, - timeout);
Iterator<Entry<String, DBSession>> entries = sessionList.entrySet().iterator();
while (entries.hasNext()) {
Entry<String, DBSession> entry = entries.next();
DBSession session = entry.getValue();
if (session.getAccessTime().before(cal.getTime())) {
// close connection
try {
connMgr.closeconn(session.getConnection(), entry.getKey());
} catch (Exception e) {
e.printStackTrace();
}
entries.remove();
}
}
}
到connMgr(的ConnectionManager對象)的調用是有點令人費解,但我在重構遺留代碼的過程,這是它當時是什麼。會話對象存儲到數據庫的連接以及一些關聯的數據。
附註:單元測試一般不應該測試任何在後臺工作的東西(在單獨的線程中)。所以你可以分解邏輯並在另一個線程中運行它。第一個可以通過單元測試輕鬆測試,第二個 - 通過功能/驗收測試 – zerkms 2012-04-05 03:21:23
您正在測試的代碼是否調用'System.getCurrentTimeMillis()'(或類似的東西'new Date()') )?如果是這樣,這是一種可測試性反模式;你想把它委派給一個「時間源」類,你可以注入。然後,您可以使用模擬時間源進行測試。如果您可以發佈您想要測試的源代碼,我可以幫助您瞭解如何執行我的建議。 – 2012-04-05 08:40:22
@DavidWallace - 我只是假設GetInstance就是這個調用。 JavaDocs確認'Calendar的getInstance方法返回一個Calendar對象,它的時間字段已經用當前的日期和時間初始化了:' – Gishu 2012-04-05 11:20:31