본문 바로가기

TIL(Today I Learned)

TIL-231017(Jacoco로 코드 커버리지 측정(2))

📝오늘 공부한 것

  • 실전프로젝트 - '행동대장' 테스트 코드 작성하기
  • 커리어톤 참여하기

 

📌 Jacoco로 코드 커버리지 측정하기

[ JwtUtil의 Access Token 유효성 검사 메서드 ]

    public boolean validateAccessToken(String token) {
        try {
            Jwts.parserBuilder().setSigningKey(accessTokenKey).build().parseClaimsJws(token);
            return true;
        } catch (SecurityException | MalformedJwtException | SignatureException e) {
            log.error("Invalid Access JWT signature, 유효하지 않는 JWT 서명 입니다.");
            throw new IllegalArgumentException("유효하지 않는 JWT 서명 입니다.");
        } catch (ExpiredJwtException e) {
            log.error("Expired JWT Access token, 만료된 JWT token 입니다.");
            throw new IllegalArgumentException("만료된 JWT token 입니다.");
        } catch (UnsupportedJwtException e) {
            log.error("Unsupported Access JWT token, 지원되지 않는 JWT 토큰 입니다.");
            throw new IllegalArgumentException("지원되지 않는 JWT 토큰 입니다.");
        } catch (IllegalArgumentException e) {
            log.error("Access JWT claims is empty, 잘못된 JWT 토큰 입니다.");
            throw new IllegalArgumentException("잘못된 JWT 토큰 입니다.");
        }
    }

Access Token 유효성 검사 메서드의 실패 테스트 코드를 작성하였다. 이 메서드는 토큰을 증하고 예외를 던진다.

'"유효하지 않는 JWT 서명입니다.","만료된 JWT token입니다.","지원되지 않는 JWT 토큰입니다.","잘못된 JWT 토큰입니다."' 각각에 대한 실패 코드를 작성하고 테스트를 수행하였다.

    @Nested
    @DisplayName("accessToken 유효성 검사 실패")
    class validateAccessTokenFail{
        @Test
        @DisplayName("accessToken 유효성 검사 실패 - 유효하지 않은 JWT")
        void validateAccessTokenFail1(){
            String token = "wrong token";
            assertThrows(IllegalArgumentException.class,()->{
                jwtUtil.validateAccessToken(token);
            });
        }

        @Test
        @DisplayName("accessToken 유효성 검사 실패 - 만료된 JWT")
        void validateAccessTokenFail2(){
            String token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0IiwiYXV0aCI6IlVTRVIiLCJleHAiOjE2OTU1MzQ0OTksImlhdCI6MTY5NTUzMDg5OX0.CouyX_QtF8Sy9E1Iin2NmsJmubRgNQ2OuGSGjNMZZ2g";
            assertThrows(IllegalArgumentException.class,()->{
                jwtUtil.validateAccessToken(token);
            });
        }

        @Test
        @DisplayName("accessToken 유효성 검사 실패 - 지원되지 않는 JWT")
        void validateAccessTokenFail3(){
            String token = "eyJhbGciOiJOT05FIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.DjwRE2RJ21X_p-BzUI1OlYh8i4SKLIZryRrRPcXG5Bc";
            assertThrows(IllegalArgumentException.class,()->{
                jwtUtil.validateAccessToken(token);
            });
        }

        @Test
        @DisplayName("accessToken 유효성 검사 실패 - 잘못된 JWT")
        void validateAccessTokenFail4(){
            String token = " ";
            assertThrows(IllegalArgumentException.class,()->{
                jwtUtil.validateAccessToken(token);
            });
        }
    }

 

validateAccessToken메서드 테스트에 사용될 토큰을 넣어주어야 하는데, 이때 토큰을 실제 상황에 맞게 넣어주어야 했다.

유효하지 않은 JWT, 만료된 JWT, 잘못된 JWT의 경우는 테스트가 잘 되었는데, 지원되지 않는 JWT의 케이스를 테스트하려고 지원되지 않는 형식의 JWT를 만들어서 넣어주면, 유효하지 않는 JWT나 잘못된 JWT 쪽의 예외가 터지는 것이었다.

 

이렇게 '지원되지 않는 JWT'의 테스트 코드를 실행하면,  

유효하지 않는 JWT 서명의 예외가 발생한다.

 

validateAccessToken 메서드에서는 HS256 또는 다른 암호화 알고리즘이 필요하기 때문에, SignatureException 또는 MalformedJwtException 등의 예외가 먼저 발생할 수 있다고 한다. 이 때문에, UnsupportedJwtException의 예외를 발생시키는 테스트 케이스를 만드는 것은 어려워 강제로 예외를 발생시켜줘야 한다는 것이었다.

 

테스트 코드의 주목적은 내가 개발한 기능들이 잘 동작하는지 확인하는 것이지, 강제로 예외를 발생시켜 코드 커버리지를 채우는 것은 의미가 없다고 생각했다. 따라서, 이 부분에 대해서는 커버리지를 채우지 않고 놔두기로 하였다.

 

 

코드 커버리지를 100% 채우는 것이 중요한 것인가? 에 대한 생각을 많이 했던 것 같다.
코드커버리를 채우는 것도 중요하지만, 의미 있는 테스트를 작성하고 코드를 검증하는 것이 더 중요하다는 것을 느꼈다.

 

 

Jacoco 설정하기
👉🏻 2023.10.12 - [TIL(Today I Learned)] - TIL-231012(Jacoco로 코드 커버리지 측정(1))
테스트 실행 시 예외 메시지를 가져오지 않음
👉🏻 2023.10.13 - [TIL(Today I Learned)] - TIL-231013(테스트 실행 시 예외 메시지를 가져오지 않는 문제)
의미있는 테스트 코드 작성이란 무엇일까..
👉🏻 2023.10.17 - [TIL(Today I Learned)] - TIL-231017(Jacoco로 코드 커버리지 측정(2))
테스트 코드 결과
👉🏻 2023.10.18 - [TIL(Today I Learned)] - TIL-231018(Jacoco로 코드 커버리지 측정(3))