How to check jUnit test transit time without access to private variables?

I am testing a module where I need a certain amount of time before I can check the results. In particular, I need to take a minute x before I can tell if the test worked or not. I read that in unit testing we should test the interface, not the implementation, so we should not use private variables, but besides the fact that I slept in my unit test, I don’t know how to test without changing the private variables.

My test is configured as follows:

@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));
}

Is it possible to check this, apart from changing the private variable accessTime (by creating setAccessTime setter or reflection) or inserting sleep in the unit test?

EDIT 11-April-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) , , , . Session , .

+5
4
  • , . , , ...

.

public void TestClearSessionsMaintainsSessionsUnlessLastAccessTimeIsOverThreshold() {

    final int timeout = 1;
    final String sessionId = "test";
    sessionMgr = GetSessionManagerWithTimeout(timeout);
    DBSession session = CreateSession(sessionMgr, sessionId);

    sessionMgr.clearSessions();
    assertNotNull(sessionMgr.getSession(sessionId));

    session.setAccessTime(PastInstantThatIsOverThreshold()); // MODIFY PRIVATE VARIABLE VIA PROTECTED SETTER
    sessionMgr.clearSessions();
    assertNull(sessionMgr.getSession(sessionId));
}
  • , ,
    • ? , , ?
    • / - , . , Clock , . MockClock, getCurrentTime() , . .. , .

.

public void TestClearSessionsMaintainsSessionsUnlessLastAccessTimeIsOverThreshold() {

      final int timeout = 1;
      final String sessionId = "test";
      expect(mockClock).GetCurrentTime(); willReturn(CurrentTime());
      sessionMgr = GetSessionManagerWithTimeout(timeout, mockClock);
      DBSession session = CreateSession(sessionMgr, sessionId);

      sessionMgr.clearSessions();
      assertNotNull(sessionMgr.getSession(sessionId));

      expect(mockClock).GetCurrentTime(); willReturn(PastInstantThatIsOverThreshold());
      session.DoSomethingThatUpdatesAccessTime();
      sessionMgr.clearSessions();
      assertNull(sessionMgr.getSession(sessionId));
}
+4

EDIT: , . , .

? , , , , "test", -, ?

- , , , , (, zerkms).

unit test , / , . - . , , , , .

:

class MyClass {
  public void doSomethingThatNeedsTime(int timeout) {
    Date now = getNow();
    if (new Date().getTime() > now.getTime() + timeout) {
      // timed out!
    }
  }

  Date getNow() {
    return new Date();
  }
}

class TestMyClass {
  @Test
  public void testDoSomethingThatNeedsTime() {
    MyClass mc = new MyClass() {
      Date getNow() {
        // return a time appropriate for my test
      }    
    };

    mc.doSomethingThatNeedsTime(1);

    // assert
  }
}

, , , . getNow(), . , .

, , REAL getNow() , , - . , . , .

, ( ), , . , - getNow(), .

+1

, - SessionManager evitcs .

, DBSession.

AlwaysExpiredDBSession extends DBSession  {
....
// access time to be somewhere older 'NOW'

}
+1

fooobar.com/questions/1108744/..., , , - ( ). , JodaTime Mockito.

, (. fooobar.com/questions/71263/...). :

import org.joda.time.DateTime;

public interface Clock {
    public DateTime getCurrentDateTime() ;
}

:

import org.joda.time.DateTime;

public class JodaClock implements Clock {

    @Override
    public DateTime getCurrentDateTime() {
        return new DateTime();
    }

}

SessionManager:

SessionManager(ConnectionManager connMgr, SessionGenerator sessionGen,
        ObjectFactory factory, Clock clock) {

, , ( "t" testClear... "", , ...):

@Test
public void testClearSessionsMaintainsSessionsUnlessLastAccessTimeIsOverThreshold() {
    final String sessionId = "test";
    final Clock mockClock = mock(Clock.class);

    when(mockClock.getCurrentDateTime()).thenReturn(getNow());
    SessionManager sessionMgr = getSessionManager(connMgr,
            sessionGen, factory, mockClock);
    createSession(sessionMgr, sessionId);

    sessionMgr.clearSessions(defaultTimeout);
    assertNotNull(sessionMgr.getSession(sessionId));

    when(mockClock.getCurrentDateTime()).thenReturn(getExpired());

    sessionMgr.clearSessions(defaultTimeout);
    assertNull(sessionMgr.getSession(sessionId));
}

, Session.setAccessTime() testOnlyExpiredSessionsared(), , , . fooobar.com/questions/269194/... SessionManager.clearSessions(), , SessionManager, DBSession.

From:

if (session.getAccessTime().before(cal.getTime())) {

To:

if (session.isExpired(expireTime)) {

mockSession ( Jayan fooobar.com/questions/1108744/...)

@Test
public void testOnlyOldSessionsCleared() {
    final String sessionId = "test";
    final String sessionId2 = "test2";

    ObjectFactory mockFactory = spy(factory);
    SessionManager sm = factory.createSessionManager(connMgr, sessionGen,
        mockFactory, clock);

    // create expired session
    NPIISession session = factory.createNPIISession(null, clock);
    NPIISession mockSession = spy(session);
    // return session expired
    doReturn(true).when(mockSession).isExpired((DateTime) anyObject());

    // get factory to return mockSession to sessionManager
    doReturn(mockSession).when(mockFactory).createDBSession(
        (Connection) anyObject(), eq(clock));
    createSession(sm, sessionId);

    // reset factory so return normal session
    reset(mockFactory);
    createSession(sm, sessionId2);

    assertNotNull(sm.getSession(sessionId));
    assertNotNull(sm.getSession(sessionId2));

    sm.clearSessions(defaultTimeout);
    assertNull(sm.getSession(sessionId));
    assertNotNull(sm.getSession(sessionId2));
}

Thanks to everyone for helping with this. Please let me know if you see any problems with the changes.

0
source

All Articles