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()
}
테스트가 성공적으로 동작하는 모습을 볼 수 있다!