結果を確認する前に一定の時間が必要なクラスの単体テストを行っています。具体的には、テストが機能したかどうかを判断するには、x 分かかる必要があります。単体テストでは、実装ではなくインターフェイスをテストする必要があるため、プライベート変数にアクセスするべきではないことを読みましたが、単体テストでスリープ状態にする以外に、プライベート変数を変更せずにテストする方法がわかりません。
私のテストは次のように設定されています:
@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));
}
(setAccessTime セッターまたはリフレクションを作成して) accessTime プライベート変数を変更するか、単体テストにスリープを挿入する以外に、これをテストすることは可能ですか?
2012年4月11日編集
特定の時間が経過した後に 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 オブジェクト) への呼び出しは少し複雑ですが、私はレガシー コードをリファクタリングしている最中であり、現時点ではそうなっています。Session オブジェクトには、データベースへの接続と関連データが格納されます。