1. Mockito란?
- Mockito는 Java 진영에서 가장 인기 있는 mocking 프레임워크입니다.
- 단위 테스트를 작성할 때 테스트 대상 코드가 의존하는 객체들을 가짜(mock)로 대체하여 테스트를 용이하게 만들어줍니다.
- 예를 들어, 데이터베이스나 외부 API에 의존하는 코드를 테스트할 때 실제 데이터베이스나 API 대신 Mockito로 만든 가짜 객체를 사용할 수 있습니다.
1.1 테스트 더블의 종류
- Mockito에서 제공하는 대표적인 테스트 더블은 다음과 같습니다
- Mock: 가짜 객체를 생성하여 그 객체의 모든 행동 을 프로그래밍할 수 있습니다.
- Spy: 실제 객체를 감싸서 일부 메서드만 가짜로 대체할 수 있습니다.
- Stub: 미리 준비된 답변으로 메서드 호출에 응답하는 객체입니다.
2. Mockito 5 설정하기
2.1 의존성 추가
최신 Spring Boot 3.x 프로젝트를 사용한다면 별도의 설정 없이 spring-boot-starter-test에 Mockito가 포함되어 있습니다. 하지만 수동으로 설정해야 하는 경우 다음과 같이 의존성을 추가합니다:
Maven의 경우
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.14.2</version>
<scope>test</scope>
</dependency>
Gradle의 경우
testImplementation 'org.mockito:mockito-core:5.14.2'
2.2 JUnit 5와 통합
- Mockito 5는 JUnit 5와 원활하게 통합됩니다.
@ExtendWith(MockitoExtension.class)를 사용하여 Mockito의 기능을 JUnit 테스트에서 사용할 수 있습니다:
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
// 테스트 코드
}
3. Mock 객체 생성하기
Mock 객체를 생성하는 방법은 크게 두 가지가 있습니다.
3.1 애노테이션을 사용한 방법
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository; // Mock 객체 생성
@InjectMocks
private UserService userService; // Mock을 주입받는 대상
// 테스트 메서드...
}
@Mock: Mock 객체를 생성합니다.@InjectMocks:@Mock으로 생성된 객체를 자동으로 주입받습니다.
3.2 직접 생성하는 방법
UserRepository userRepository = mock(UserRepository.class);
UserService userService = new UserService(userRepository);
- 이 방법은 테스트 메서드 내에서 지역적으로 Mock 객체가 필요할 때 유용합니다.
4. Stubbing: Mock 객체의 행동 정의하기
- Stubbing은 Mock 객체가 어떻게 동작해야 하는지 정의하는 것입니다.
4.1 기본적인 Stubbing
// Mock 객체의 메서드가 특정 값을 반환하도록 설정
when(userRepository.findById(1L))
.thenReturn(Optional.of(new User(1L, "John")));
// BDD 스타일로도 같은 동작을 정의할 수 있습니다
given(userRepository.findById(1L))
.willReturn(Optional.of(new User(1L, "John")));
4.2 여러 번 호출될 때의 동작
// 순차적으로 다른 값을 반환하도록 설정
when(userRepository.findById(1L))
.thenReturn(Optional.of(user1)) // 첫 번째 호출
.thenReturn(Optional.of(user2)) // 두 번째 호출
.thenThrow(new RuntimeException()); // 세 번째 호출
4.3 조건부 응답
// 메서드 호출 시 전달된 인자에 따라 다른 동작을 하도록 설정
when(userRepository.findById(anyLong()))
.thenAnswer(invocation -> {
Long id = invocation.getArgument(0);
if (id < 0) {
throw new IllegalArgumentException("Invalid ID");
}
return Optional.of(new User(id, "User " + id));
});
5. 검증(Verification)
- 검증은 Mock 객체의 메서드들이 예상대로 호출되었는지 확인하는 과정입니다.
- Mockito에서는
verify메서드를 사용하여 검증을 수행합니다. - 검증은 Mock 객체가 실제로 사용되는 방식을 확인하고 테스트 대상 코드의 동작을 검증하는 데 도움이 됩니다.