ReflectionTestUtils을 이용하여 단위테스트 작성하기

hanana·2024년 1월 19일
0
post-custom-banner
class UserServiceImpl (
    private val userRepository: UserRepository,
    private val passwordEncoder: BCryptPasswordEncoder,
) : UserService{

    @Value("\${jwt.secret-key}")
    private val secretKey: String? = null
    @Value("\${jwt.token.expired-time-ms}")
 	private val expiredMs: Long? = null
    
    
    override fun login(userName: String, password: String): String {
    // 회원가입 여부 체크
    val userEntity: User = userRepository.findByUserName(userName)?:throw SnsApplicationException(ErrorCode.USER_NOT_FOUND,"$userName is not founded")

    // 비밀번호 체크
    if(!passwordEncoder.matches(password, userEntity.password)) {
        throw SnsApplicationException(ErrorCode.INVALID_PASSWORD)
    }
    // 토큰 생성
    val result = generateToken(userName, secretKey, expiredMs)

    return result
    }
}
    

로그인 검증을 거쳐 유효한 정보가 들어오면
jwt 토큰을 return 해주는 서비스 코드이다.

이를 위한 테스트코드는 아래와 같다.

@Test
fun 로그인이_정상적으로_동작하는_경우() {
   val userRepository = FakeUserRepository()
   val passwordEncoder = FakePasswordEncoder()
   val userService = UserServiceImpl(userRepository,passwordEncoder)
   //given
   val userName: String = "userName"
   val password: String = "password"
   val user = User.fixture(userName, passwordEncoder.encode(password))
   userRepository.save(user)
   
   //when
   val token = userService.login(userName, password)
   
   //TODO 검증로직 작성
   println(token)
}

테스트를 돌려보면

테스트코드로 실행시
토큰생성 부분에서 generateToken 메소드를 실행할 때 secretKey와 exporedMs 을 주어주지 않아서 발생한 문제이다.

하지만 문제는 해당 값은 Spring Container에 의해서 관리되고 있는 값이라는 문제가 발생한다.

스프링에서는 이러한 문제를 해결하기위해 ReflectionTestUtils 라는 유틸리티 메소드를 제공한다.

@Test
fun 로그인이_정상적으로_동작하는_경우() {
    val userRepository = FakeUserRepository()
    val passwordEncoder = FakePasswordEncoder()
    val userService = UserServiceImpl(userRepository,passwordEncoder)

    //given
    val userName: String = "userName"
    val password: String = "password"
    val user = User.fixture(userName, passwordEncoder.encode(password))
    userRepository.save(user)


    // ReflectionTestUtils를 사용하여 private 필드에 값을 주입
    ReflectionTestUtils.setField(userService, "secretKey", "hanatestcode.abcdefghijklmn.secret_key")
    ReflectionTestUtils.setField(userService, "expiredMs", 360000L)

    //when
    val token = userService.login(userName, password)
    //TODO 검증로직 작성
    println(token)
    assertThat(token.startsWith("Bearer ")).isTrue()
}

테스트가 성공적으로 동작하는 모습을 볼 수 있다!

profile
성숙해지려고 노력하지 않으면 성숙하기까지 매우 많은 시간이 걸린다.
post-custom-banner

0개의 댓글