T_era
테스트 코드 mock()과 ReflectionTestUtils 본문
Mockito의 mock()과 ReflectionTestUtils 정리
1. mock() 메서드
기본 개념
- Mockito의 정적 메서드로, Mock 객체를 생성
- @Mock 어노테이션과 동일한 기능을 수행하지만, 코드에서 직접 호출
- 테스트 메서드 내에서 일시적으로 Mock 객체가 필요할 때 유용
사용 예시
@Test
void test_with_mock() {
// Mock 객체 생성
UserRepository userRepository = mock(UserRepository.class);
PasswordEncoder passwordEncoder = mock(PasswordEncoder.class);
// Mock 객체 동작 정의
when(userRepository.findById(1L)).thenReturn(Optional.of(new User()));
when(passwordEncoder.encode("password")).thenReturn("encodedPassword");
// 테스트 대상 객체에 Mock 주입
UserService userService = new UserService(userRepository, passwordEncoder);
// 테스트 실행
userService.changePassword(1L, new UserChangePasswordRequest("old", "new"));
// 검증
verify(userRepository).findById(1L);
}
@Mock vs mock()
@Mock
UserRepository userRepository;
// mock() 사용
UserRepository userRepository = mock(UserRepository.class);
2. ReflectionTestUtils
기본 개념
- Spring Framework의 테스트 유틸리티
- private 필드에 접근하거나 값을 설정할 때 사용
- 리플렉션을 사용하여 객체의 private 멤버에 접근
주요 메서드
- setField(): private 필드에 값 설정
- getField(): private 필드의 값 조회
- invokeMethod(): private 메서드 호출
사용 예시
@Test
void test_private_field() {
// given
UserService userService = new UserService();
UserRepository userRepository = mock(UserRepository.class);
// private 필드에 Mock 객체 주입
ReflectionTestUtils.setField(userService, "userRepository", userRepository);
// when
when(userRepository.findById(1L)).thenReturn(Optional.of(new User()));
// then
User user = userService.findUser(1L);
assertThat(user).isNotNull();
}
2. private 필드 값 조회
@Test
void test_get_private_field() {
// given
UserService userService = new UserService();
UserRepository userRepository = mock(UserRepository.class);
ReflectionTestUtils.setField(userService, "userRepository", userRepository);
// when
Object fieldValue = ReflectionTestUtils.getField(userService, "userRepository");
// then
assertThat(fieldValue).isEqualTo(userRepository);
}
3. private 메서드 호출
@Test
void test_private_method() {
// given
UserService userService = new UserService();
// when
String result = (String) ReflectionTestUtils.invokeMethod(
userService,
"validatePassword",
"password123"
);
// then
assertThat(result).isNotNull();
}
실제 사용 예시
1. 의존성 주입 테스트
Apply to build.gradle
2. private 메서드 테스트
@Test
void test_private_validation() {
// given
UserService userService = new UserService();
// when
boolean result = (boolean) ReflectionTestUtils.invokeMethod(
userService,
"isValidPassword",
"password123"
);
// then
assertThat(result).isTrue();
}
주의사항
- ReflectionTestUtils는 테스트 코드에서만 사용
- private 멤버에 접근하는 것은 캡슐화를 깨뜨릴 수 있음
- 가능하면 public 메서드를 통해 테스트하는 것이 좋음
- 꼭 필요한 경우에만 사용
사용이 필요한 경우
- private 필드에 의존성 주입이 필요한 경우
- private 메서드의 로직을 직접 테스트해야 하는 경우
- 테스트를 위해 private 필드의 값을 확인해야 하는 경우
- Spring의 자동 주입이 어려운 테스트 환경에서 사용
'Programing > Spring' 카테고리의 다른 글
| 트랜잭션 전파는 상황마다 어떤 속성을 써야할까? (0) | 2025.06.10 |
|---|---|
| 상속매핑 전략과 선택 가이드 (0) | 2025.06.10 |
| 테스트 코드 어노테이션 및 메서드 정리 (0) | 2025.06.09 |
| API 로깅 Interceptor VS AOP (1) | 2025.06.05 |
| N+1 문제와 페치 조인 적용해 해결하기 (1) | 2025.06.02 |