Service 테스트 코드 - @ExtendWith(MockitoExtension.class)

이주호·2024년 1월 29일

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)UserRepositoryfindByUsername 메서드가 특정 인자로 호출될 때 어떤 값을 반환할지를 설정한다.
이를 통해 userService.findUserByUsername(username) 메서드 호출 시 예상하는 결과를 검증할 수 있다.

이렇게 Mockito를 사용하여 서비스의 메서드를 테스트하면, 서비스가 의존하는 Repository 등의 객체들을 Mocking하여 별도의 데이터베이스 연결 없이 테스트를 수행할 수 있다.

profile
코드 위에서 춤추고 싶어요

0개의 댓글