userService를 모키토를 이용한 단위 테스트 중
jwtUtil 을 @Spy로 선언 하니 아래와 같은 에러 발생
Please ensure that the type 'JwtUtil' has a no-arg constructor.
JwtUtil에 빈생성자가 있는지 확인 해라.~
jwtUtil
@Slf4j
@Component
@RequiredArgsConstructor
public class JwtUtil {
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String REFRESH_TOKEN_HEADER = "RefreshToken";
public static final String AUTHORIZATION_KEY = "auth";
private static final String BEARER_PREFIX = "Bearer ";
private static final long TOKEN_TIME = 30 * 60 * 1000L; //30 min
private static final long REFRESH_TOKEN_TIME = 60 * 60 * 1000L * 24 * 14; //2week
private final UserDetailsServiceImpl userDetailService;
@Value("${jwt.secret.key}")
private String secretKey;
private Key key;
private final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
Test
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Spy
private JwtUtil jwtUtil;
@BeforeEach
void prepare() {
ReflectionTestUtils.setField(jwtUtil,
"secretKey", // jwtUtil의 secretKey값이 저장될 변수
"7ZWt7ZW0OTntmZTsnbTtjIXtlZzqta3snYTrhIjrqLjshLjqs4TroZzrgpjslYTqsIDsnpDtm4zrpa3tlZzqsJzrsJzsnpDrpbzrp4zrk6TslrTqsIDsnpA="); // secretKey의 값
jwtUtil.init(); // jwtUtil에서 @PostConstructor가 동작하지 않기 때문에, 임의로 실행시켜야 함
}
@Spy
private BCryptPasswordEncoder passwordEncoder;
@Test
@DisplayName("회원가입")
void signup() {
//given 입력값 리턴값
SignupRequest request = SignupRequest.builder()
.username("pororo")
.password("pororo1234")
.email("pororo@naver.com")
.admin(false)
.adminToken(null)
.build();
when(userRepository.findByUsername(any(String.class)))
.thenReturn(Optional.empty());
//when
ResponseStatusDto response = userService.signup(request);
//then
assertThat(response.getStatusCode()).isEqualTo(StatusEnum.SIGNUP_SUCCESS.getStatusCode());
assertThat(response.getMsg()).isEqualTo(StatusEnum.SIGNUP_SUCCESS.getMsg());
verify(userRepository, times(1)).save(any(User.class));
}
그래서 위의 기존 코드에 @NoArgsConstructor를 입력하면 위에 private final 로 선언된UserDetailsServiceImpl userDetailService에 빨간줄로 에러가 발생한다. 빨간줄의이유는 @NoArgsConstructor로 빈생성자를 만들지만 final로 선언했지않는가? 그래서 매게변수를 꼭! 가져야하기 때문에 오류가 발생한다.
그럼 현재 코드에서 빈생성자를 사용하지 않고 , 테스트 코드에서 jwtUtil을 빈으로 주입하는 방법은??
@InjectMocks으로 jwtUtil을 주입하면 된다.
@InjectMocks
private JwtUtil jwtUtil;
테스트 코드
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@InjectMocks
private JwtUtil jwtUtil;
@BeforeEach
void prepare() {
ReflectionTestUtils.setField(jwtUtil,
"secretKey", // jwtUtil의 secretKey값이 저장될 변수
"7ZWt7ZW0OTntmZTsnbTtjIXtlZzqta3snYTrhIjrqLjshLjqs4TroZzrgpjslYTqsIDsnpDtm4zrpa3tlZzqsJzrsJzsnpDrpbzrp4zrk6TslrTqsIDsnpA="); // secretKey의 값
jwtUtil.init(); // jwtUtil에서 @PostConstructor가 동작하지 않기 때문에, 임의로 실행시켜야 함
}
@Spy
private BCryptPasswordEncoder passwordEncoder;
@Test
@DisplayName("회원가입")
void signup() {
//given 입력값 리턴값
SignupRequest request = SignupRequest.builder()
.username("pororo")
.password("pororo1234")
.email("pororo@naver.com")
.admin(false)
.adminToken(null)
.build();
when(userRepository.findByUsername(any(String.class)))
.thenReturn(Optional.empty());
//when
ResponseStatusDto response = userService.signup(request);
//then
assertThat(response.getStatusCode()).isEqualTo(StatusEnum.SIGNUP_SUCCESS.getStatusCode());
assertThat(response.getMsg()).isEqualTo(StatusEnum.SIGNUP_SUCCESS.getMsg());
verify(userRepository, times(1)).save(any(User.class));
}