자바칩
[Spring] @InjectMocks 와 @Mock 의 차이점 본문
728x90
@InjectMocks와 @Mock 어노테이션의 사용은 각기 다른 목적을 가지고 있습니다. 이를 통해 단위 테스트에서 객체 간의 의존성을 효과적으로 관리하고, 테스트 대상 객체와 그 의존 객체를 올바르게 설정할 수 있습니다.
@Mock
- 역할: 특정 클래스의 목(mock) 객체를 생성합니다.
- 사용 위치: 테스트에서 사용되는 의존 객체에 대해 사용됩니다.
- 목적: 목 객체를 통해 실제 객체의 동작을 시뮬레이션하고, 특정 메서드 호출에 대해 정의된 동작을 수행하도록 합니다.
@Mock
private UserRepository userRepository;
@Mock
private PasswordEncoder passwordEncoder;
위 예시에서는 UserRepository와 PasswordEncoder가 목 객체로 생성되었습니다. 이는 실제 객체를 대체하여 메서드 호출 시 원하는 동작을 정의할 수 있게 합니다.
@InjectMocks
- 역할: 테스트 대상 객체를 생성하고, 이 객체의 의존성을 자동으로 주입합니다.
- 사용 위치: 테스트 대상 클래스에 대해 사용됩니다.
- 목적: 의존성이 있는 객체를 주입받아, 테스트 대상 클래스의 실제 동작을 검증할 수 있도록 합니다.
@InjectMocks
private UserService userService;
위 예시에서는 UserService 객체가 생성되고, @Mock으로 정의된 객체들이 UserService의 의존성으로 주입됩니다. 이렇게 하면 UserService는 실제 실행될 때와 동일한 의존성을 가지게 되어, 목 객체와의 상호작용을 통해 그 동작을 검증할 수 있습니다.
종합 예시
@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
@InjectMocks
private UserService userService;
@Mock
private UserRepository userRepository;
@Mock
private PasswordEncoder passwordEncoder;
@Test
public void createUser_success() {
// Given: 사용자 정보 설정
UserDto userDto = new UserDto();
userDto.setUsername("newUser");
userDto.setPassword1("password");
userDto.setPassword2("password");
// When: 목 객체의 동작 정의
when(userRepository.findByUsername(userDto.getUsername())).thenReturn(Optional.empty());
when(passwordEncoder.encode(userDto.getPassword1())).thenReturn("encodedPassword");
// 목 객체가 반환할 사용자 설정
User savedUser = new User();
savedUser.setId(1L);
when(userRepository.save(any(User.class))).thenReturn(savedUser);
// Then: 서비스 메서드 호출 및 결과 검증
Long userId = userService.createUser(userDto);
// 결과가 예상대로인지 검증
assertEquals(1L, userId);
// save 메서드가 정확히 한 번 호출되었는지 검증
verify(userRepository, times(1)).save(any(User.class));
}
}
verify는 Mockito 라이브러리에서 제공하는 메서드로, 특정 메서드가 호출되었는지 확인하는 데 사용됩니다. 테스트 중에 메서드 호출 여부와 호출 횟수를 검증할 수 있습니다. 이를 통해 특정 조건에서 메서드가 제대로 호출되었는지 확인하여 코드의 동작을 검증할 수 있습니다.
결론
- @Mock: 의존 객체를 목(mock) 객체로 생성하여 메서드 호출에 대한 동작을 정의합니다.
- @InjectMocks: 테스트 대상 객체를 생성하고, 목 객체들을 해당 객체의 의존성으로 주입합니다.
이렇게 함으로써, UserService 클래스는 테스트 환경에서 실제 환경과 유사한 의존성을 가지게 되어, 그 동작을 검증할 수 있습니다.
테스트 코드를 처음 작성해보면서 @Mock과 @InjectMocks을 왜 따로 쓰는 것일까 궁금해서 찾아보았다.
@Mock 객체 (테스트에 사용되는 의존 객체) -> @InjectMocks (테스트 대상 객체) 에 주입
이름 앞에 Inject(주입)를 다는 이유는 다 있는 것이구나 싶다.
'Study > Spring' 카테고리의 다른 글
[Spring] @MockBean (0) | 2024.07.19 |
---|---|
[Spring] @RunWith/@ExtendWith 와 @WebMvcTest 의 차이점 (0) | 2024.07.19 |
[Spring] 디자인 패턴 (0) | 2024.06.10 |
[Spring] 객체 지향 설계 5원칙 (SOLID) (0) | 2024.06.10 |
[Spring] 객체 지향의 4대 특성 => 캡상추다 (0) | 2024.06.10 |