public Pair<Long, Jwts> refresh(String refreshToken) {
        JwtClaims claims = refreshTokenProvider.getJwtClaimsFromToken(refreshToken);

        Long userId = JwtClaimsParserUtil.getClaimsValue(claims, RefreshTokenClaimKeys.USER_ID.getValue(), Long::parseLong);
        String role = JwtClaimsParserUtil.getClaimsValue(claims, RefreshTokenClaimKeys.ROLE.getValue(), String.class);
        log.debug("refresh token userId : {}, role : {}", userId, role);

        RefreshToken newRefreshToken;
        try {
            newRefreshToken = refreshTokenService.refresh(userId, refreshToken, refreshTokenProvider.generateToken(RefreshTokenClaim.of(userId, role)));
            log.debug("new refresh token : {}", newRefreshToken.getToken());
        } catch (IllegalArgumentException e) {
            throw new JwtErrorException(JwtErrorCode.EXPIRED_TOKEN);
        } catch (IllegalStateException e) {
            throw new JwtErrorException(JwtErrorCode.TAKEN_AWAY_TOKEN);
        }

        String newAccessToken = accessTokenProvider.generateToken(AccessTokenClaim.of(userId, role));
        log.debug("new access token : {}", newAccessToken);

        return Pair.of(userId, Jwts.of(newAccessToken, newRefreshToken.getToken()));
    }
@Test
    @DisplayName("사용자 아이디에 해당하는 다른 리프레시 토큰이 저장되어 있을 시, 탈취되었다고 판단하고 토큰을 제거한 후 JwtErrorException을 발생시킨다.")
    public void RefreshTokenRefreshFail() {
        // given
        RefreshToken refreshToken = RefreshToken.builder()
                .userId(1L)
                .token("refreshToken")
                .ttl(1000L)
                .build();
        refreshTokenRepository.save(refreshToken);

        given(refreshTokenProvider.getJwtClaimsFromToken("anotherRefreshToken")).willReturn(RefreshTokenClaim.of(refreshToken.getUserId(), Role.USER.toString()));
        given(refreshTokenProvider.generateToken(any())).willReturn("newRefreshToken");

        // when
        JwtErrorException jwtErrorException = assertThrows(JwtErrorException.class, () -> jwtAuthHelper.refresh("anotherRefreshToken"));

        // then
        assertEquals("탈취 시나리오 예외가 발생하지 않았습니다.", JwtErrorCode.TAKEN_AWAY_TOKEN, jwtErrorException.getErrorCode());
        assertFalse("리프레시 토큰이 삭제되지 않았습니다.", refreshTokenRepository.existsById(refreshToken.getUserId()));
    }