본문 바로가기

카테고리 없음

내가 생각하는 서비스 계층에서 Mock을 사용하여 단위테스트를 하는 이유

오늘 프로젝트를 진행하던 중에 한 팀원이 이런 말을 했다.

"솔직히 서비스 계층에서 왜 Mock을 사용해서 단위테스트를 해야하는지 모르겠다.

repository까지 활용해서 DB에 데이터가 들어가고 수정되는 과정까지 테스트하는게 서비스 계층의 기능을 제대로 테스트하는게 아닌가?"

 

내 생각은 이렇다.

서비스 계층에는 비즈니스 로직이 있는데, 테스트는 이 서비스 계층의 비즈니스 로직을 검증해야 한다.

그런데, 서비스 계층이 repository에 의존하고 있기 때문에 어떤 데이터베이스를 사용하는지에 따라 테스트가 실패할 수도 있고 성공할 수도 있다.

비즈니스 로직이 아닌 다른 요소에 의해 테스트가 실패하거나 성공할 수 있게 되는 것이다.

 

그래서 repository를 Mocking하여 서비스 계층의 비즈니스 로직만을 테스트하는 것이다!

 

 

예를 들어, 아래와 같은 프러덕션 코드가 있다.

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {

}


@Service
public class PostService {
    private final PostRepository postRepository;
    
    public PostService(PostRepository postRepository) {
    	this.postRepository = postRepository;
    }
    
    public Post add(String content) {
        Post post = new Post(content);
        return postRepository.save(post);
    }
}

 

PostService의 add메서드를 단위테스트하려면 어떻게 하면 될까?

우선 add메서드에서 postRepository를 사용하고 있으므로, DB와 연결되어 있어야 하므로, postRepository를 Mocking한다.

 

public class PostServiceTest {

    @Mock
    private PostRepository postRepository;
    
    @InjectMocks
    private PostService postService;
    
    @BeforeEach
    void setUp() {
        MockitoAnnotations.initMocks(this);
    }
    
    @Test
    void 게시글_작성() {
    	String content = "Mockito!";
    	Post post = new Post(content);
        
        given(postRepository.save(post)).willReturn(post);
        assertThat(postService.add(postRequestDto).isEqualTo(post);
    }
}

이렇게 하면 repository와는 별개로 비즈니스 로직만을 테스트할 수 있다. (물론 이 예제에서 비즈니스 로직이랄게 없긴하다..)