
Service 테스트 코드 짜는 것도 정리하는게 좋을 것 같아 글을 쓴다. 프로젝트에서 작성한 테스트코드를 가져와 설명하기에는 뭐해서 아래 예제에서는 사용자(User) 서비스를 가정하고 테스트 코드를 작성한다.
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
@Mock
private UserRepository userRepository; // UserRepository는 실제로는 Mock 객체로 대체됩니다.
@InjectMocks
private UserService userService; // UserService에 @Mock이나 @Spy로 설정된 객체들을 주입합니다.
@Test
public void testFindUserByUsername() {
// given
String username = "john_doe";
User expectedUser = new User(1L, "john_doe", "John", "Doe");
// UserRepository의 findByUsername 메서드가 호출될 때 특정 인자로 무조건 expectedUser를 반환하도록 가정합니다.
given(userRepository.findByUsername(username)).willReturn(expectedUser);
// when
User foundUser = userService.findUserByUsername(username);
// then
assertEquals(expectedUser, foundUser);
}
// 여러 다른 테스트 케이스를 추가할 수 있습니다.
}
위의 예제에서는 @ExtendWith(MockitoExtension.class)를 사용하여 Mockito를 확장한다. 그리고 @Mock 어노테이션을 사용하여 UserRepository를 Mock 객체로 만들어준다. @InjectMocks 어노테이션은 UserService에 @Mock으로 설정된 객체들을 주입한다. 이 때, 테트스하는 Service클래스에서 사용하는 모든 repository와 다른 빈들도 @Mock으로 Mock 객체를 만들어줘야한다.
given(userRepository.findByUsername(username)).willReturn(expectedUser)는 UserRepository의 findByUsername 메서드가 특정 인자로 호출될 때 어떤 값을 반환할지를 설정한다.
이를 통해 userService.findUserByUsername(username) 메서드 호출 시 예상하는 결과를 검증할 수 있다.
이렇게 Mockito를 사용하여 서비스의 메서드를 테스트하면, 서비스가 의존하는 Repository 등의 객체들을 Mocking하여 별도의 데이터베이스 연결 없이 테스트를 수행할 수 있다.