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.