본문 바로가기
Project/모면

[Spring Boot] 테스트 코드에서 프로퍼티 NullPointerException 오류 해결

by 독서왕뼝아리 2023. 4. 6.

 

@Service
public class TokenService {

    @Value("${secret}")
    private String secretKey;


    public String generateJWT(MemberInfoDto info) {
    	// ...
        Jwts.builder()
                .setHeader(headers)
                .setClaims(payloads)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + 60 * 1000 * 60))
                .signWith(SignatureAlgorithm.HS256, secretKey.getBytes())
                .compact();
    }
    
    //...
    
}

토큰 암호화/복호화 서비스를 담당하는 클래스의 테스트 코드를 구현하고 싶었다. 

 

 

class TokenServiceTest {

    private final String SUBJECT = "테스트 토큰입니다.";
    private final String NAME_VALUE = "hong gli dong";
    private final String SUB_VALUE = "qwertrtrfadf";
    private final String PICTURE_VALUE = "http://asdf";

    private MemberInfoDto sample;
    private TokenService tokenService;

    @BeforeEach
    void init() {
        tokenService = new TokenService();
        sample = MemberInfoDto.builder()
                .sub(SUB_VALUE)
                .name(NAME_VALUE)
                .picture(PICTURE_VALUE)
                .build();
    }

    @Test
    void decryptJwtToken() {
        String jwt = tokenService.generateJWT(sample);
        System.out.println(jwt);
        
        MemberInfoDto result = tokenService.decodeJWT(jwt);

        assertEquals(result.getName(), NAME_VALUE);
        assertEquals(result.getPicture(), PICTURE_VALUE);
        assertEquals(result.getSub(), SUB_VALUE);
    }
}

위와 같이 테스트 코드를 짰는데

 

 

으잉? NullPointerException이 발생한다. secretKey 사용하는 코드에서 NPE가 발생했다. 테스트에서는 @Value로 프로퍼티 값이 주입 안 되는 것 같다.

 

 

 

스스로 생각한 방법은 쓰레기 같았다.

- 테스트 용 메서드를 생성해 secretKey만 바꾸는 방법 : 아름답지 않다

- 테스트 코드에서 비즈니스 로직을 복붙해서 로직(!)을 테스트하는 방법 : 말도 안 됨. 특히나 secret 같은 변수를 테스트에서 만지는 게. 

- @SpringBootTest 를 클래스에 선언해 프로퍼티 주입이 정상적으로 되게 하기 : 유닛테스트의 목적에 어긋난다.

 

 

 

나보다 더 똑똑한 사람들이 라이브러리로 이미 구현해 놨겠거니 다른 방법을 찾아보니!

@BeforeEach
void init() {
    tokenService = new TokenService();
    
    ReflectionTestUtils.setField(tokenService,
    		"secretKey", "sdfzxcvojhwouerdfaw4ertvwt4v34tkbvjljlr"); // 이 코드
            
    sample = MemberInfoDto.builder()
            .sub(SUB_VALUE)
            .name(NAME_VALUE)
            .picture(PICTURE_VALUE)
            .build();
}

 

BeforeEach 메서드에 한 줄의 코드를 추가하니 TokenService의 null이었던 'secretKey' field에 값이 세팅됐다는 문구와 함께 테스트가 통과됐다!!

 

 

 

참고

 

Null pointer exception while accessing property from application properties in Junit test

I have method which access property from application.properties & for which I am writing junit. class ServiceClass{ @Value("${urlfromapplicationproperties}") public String myUrl ; p...

stackoverflow.com