Skip to content
Advertisement

How deal with testing in Java for long time?

I want to test this method:

/**
  * Get the expiry date from a token
  * 
  * @param token
  * @return the expiry date
  */
  public Long getExpiryDateFromJwtToken(String token) {
    return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getExpiration().getTime();
}

And this is the test (yes, longer test than methods 🙂 ):

    @Test
    void canGetExpiryDateFromJwtToken() {

        // Set the security context
        SecurityContextHolder.setContext(securityContext);
        
        // Mock the time at.. now
        Long currentTimeMillis = System.currentTimeMillis();

        // Mock the methods
        when(timeSource.getCurrentTimeMillis()).thenReturn(currentTimeMillis);
        when(securityContext.getAuthentication()).thenReturn(authentication);
        
        // Create an usersEntitiy
        UsersEntity usersEntity = new UsersEntity(1L, "username", "password");
        // Build the entity to return from getPrincipal
        UserDetailsImpl user = UserDetailsImpl.build(usersEntity);
        when(authentication.getPrincipal()).thenReturn(user);
        
        // Finally, generate a token
        String token = jwtUtils.generateJwtToken(authentication);
        
        // Get the expiry date (our method under test)
        Long expiryDate = jwtUtils.getExpiryDateFromJwtToken(token);
        
        // Finally, assert equals
        assertEquals(currentTimeMillis+86400000, expiryDate);
    }

But, I have a small clock shift.

For example:

AssertionFailedError: expected: <1646512977798> but was: <1646512977000>

So, the time it is the same, only about 798 of difference.

Edit 1

For the moment, I solved with:

// Finally, assert equals. Accept a small clock shift
Long expectedExpiryDate = currentTimeMillis + Long.parseLong(jwtExpirationMs);
assertEquals(expectedExpiryDate/10000, expiryDate/10000);

Is there a more elegant method?

Advertisement

Answer

In general, when you work with temporal data types it’s a good idea to pass a java.time.Clock so u can set the time and control the environment.

The problem in the implementation https://github.com/bezkoder/spring-boot-spring-security-jwt-authentication/blob/master/src/main/java/com/bezkoder/springjwt/security/jwt/JwtUtils.java is with new Date(). A suggestion: Clone this implementation and make a better generateJwtToken and accept a Clock so u can control the timestamp.

Advertisement