inflearn logo
강의

Course

Instructor

Toby's Clean Spring - Domain Model Pattern and Hexagonal Architecture Part 1

Lecture Materials

서비스 단위 테스트 코드 작성

91

q1w2e306305758

1 asked

0

MemberFinder 와 같은 유즈케이스 단위로 통합 테스트를 분리 해서 작성하셨는데 단위 테스트의 경우에는 분리를 어떻게 하시나요?

MemberService (Query, Modify) 가 없이는 코드가 작성이 되질 않아서 질문 드립니다.

 

 

java spring spring-boot jpa 리팩터링 ddd

Answer 2

0

tobyilee

단위 테스트는 말 그대로 한 단위를 어떻게 정의하냐에 따라서 여러가지 접근 방법이 있습니다. 단위 테스트라고 무조건 클래스 하나만 테스트할 필요는 없습니다. 그리고 단위 테스트라고 하더라도 인터페이스를 타고 테스트하는 것이 좋고요.

애플리케이션 서비스 계층은 외부 리소스, DB 등에 의존하는 특징이 있습니다. 이걸 단위 테스트로 하려면 의존 대상에 대한 적절한 Mock, Stub 등을 만들어서 해야 합니다. 이번 강의에서 테스트를 만드는 여러가지 방식에 대해서 설명드리면서 단위 테스트를 작성하는 방법도 설명 드렸습니다. 그 부분을 참조해보시면 좋겠습니다.

아니면 다른 구체적인 케이스가 있다면 알려주세요.

0

q1w2e306305758

현재 예제 코드에 보면 MemberFinder의 테스트 코드는 @SpringBootTest 가 사용이 되어 스프링 컨테이너가 띄워진 채로 테스트를 합니다.

이를 mock을 통해 단위 테스트를 하려고 할 때 인터페이스인 MemberFinder만 테스트 하려고 해도 MemberQueryService를 Mocking해야 테스트가 가능합니다.

이럴 경우 강의에서 말씀하셨던 인터페이스 별로 테스트를 작성할 경우 기능 메서드의 위치가 이동하였을 때 테스트 코드에 변화가 없는 장점이 있다고 하셨던 부분이 깨지게 됩니다.

mock을 통한 단위 테스트를 하려면 MemberQueryService 에 의존이 되어있어 수정할 부분이 생깁니다.

이를 풀어낼 수 없는건가요?

1

tobyilee

MemberFinder를 사용하는 다른 모듈의 코드를 테스트 한다면 MemberFinder 인터페이스를 이용해서 mocking을 하는게 가능합니다.

하지만 테스트 대상이 MemberFinder라고 한다면 이를 구현한 MemberQueryService 코드가 동작해야 하므로 이걸 mocking할 수는 없죠. 테스트할 대상이 분명히 있으니까요.

나중에 query service가 커진다면 이를 적절히 분리해서 테스트할 대상의 범위를 좁힐 수 있습니다. 이때는 Finder류의 인터페이스도 더 상세한 의도에 따라서 작게 쪼갤 수도 있습니다.

단위테스트에서 Mock은 내가 테스트하려고 하는 대상(이건 구현이 반드시 포함되어야 합니다. 그러니 클래스가 테스트가 되겠죠)이 자신의 기능을 수행하는 동안에 테스트 대상이 아닌 제3의 다른 오브젝트를 이용하는 경우에 그에 대해서 적용하는 것입니다. 이 그림을 잘 그려본다면 단위 테스트 구조를 짜는 것은 어렵지 않습니다.

다만 단위 테스트를 하려고 mock을 사용하는 것이 항상 나은 선택은 아닙니다. Mock을 만드는 것은 복잡한 작업이기 때문에 테스트 속도를 떨어뜨리고, mock 적용 코드에 오류가 있을 수 있기도 합니다. 따라서 테스트가 실행되는 동안에 동작하는 기능의 범위를 여러가지 관점에서 최선의 선택을 하는 것이 필요합니다. 도메인 오브젝트처럼 외부 의존이 없거나 간단한 인터페이스에 국한되는 경우가 아닐 때는 적절한 수준의 통합 테스트가 더 나은 선택인 경우가 많습니다.

0

communityai8509

안녕하세요, 인프런 AI 인턴입니다. 생물무님.

서비스 단위 테스트에서 테스트하려는 특정 기능나 유즈케이스를 명확히 하는 것은 중요합니다. 주로 질문에서는 MemberFinder와 같은 유즈케이스 단위의 테스트 작성에 대한 궁금증을 표현하셨습니다.

서비스 단위 테스트 작성

단위 테스트는 특정 메서드나 기능을 독립적으로 테스트하는 것을 목표로 합니다. MemberService의 경우, MemberFinder와 같은 유즈케이스를 대상으로 다양한 입력과 예상되는 출력을 정의하여 테스트할 수 있습니다. 다음과 같은 방법을 고려해보세요:

  1. 모의 객체 사용(Mock): Mockito와 같은 라이브러리를 사용하여 MemberService를 모의 객체로 만들어 의존성을 제거하고 테스트를 독립적으로 수행할 수 있습니다. 이를 통해 실제 데이터베이스나 네트워크 호출 없이 서비스 계층을 테스트할 수 있습니다. Mock을 사용한 Java 단위 테스트에 대한 문서를 참조하시면 도움이 될 것입니다.

  2. 테스트 데이터 설정: 각 유즈케이스에 맞게 다양한 테스트 데이터를 설정하여 다양한 시나리오를 다룰 수 있습니다. 이는 코드의 다양한 경로와 로직을 검증하는 데 중요합니다.

  3. 의존성 분리: 특정 기능에 의존성이 많은 경우, 해당 의존성을 분리하거나 인터페이스로 추상화하여 테스트하게 되면, 유즈케이스를 보다 쉽게 테스트할 수 있습니다.

여기 서비스 테스트에 대한 또 다른 사례를 제공할 테니 이 점도 참조하여 유즈케이스에 맞는 단위 테스트를 구성하면 좋겠습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

도메인 모델에서 관계와 규칙을 구분하는 방법

0

26

2

헥사고날 아키텍처에서의 배치, 시큐리티, 비동기 이벤트 처리는 어떻게 하나요?

0

107

2

어댑터에서 도메인에 직접 의존하는 경우에 대해

0

109

2

Member 도메인이 PasswordEncoder를 받는 구조 질문 있습니다.

0

94

2

MemberService와 EmailSender 책임 분리에 대한 질문

0

98

2

NonNullApi를 NullMarked로 대체하라고 합니다.

0

120

2

39. 문서와 코드 다듬기 updateInfo 테스트 질문 있습니다.

0

69

2

Repository Adapter 설계에 대해 피드백을 부탁드립니다

0

102

2

헥사고날 part2 강의 출시 예정일 문의 드립니다.

0

240

2

PT 문의사항

0

94

1

초기 어플리케이션 구동 시 compose.yml 파싱 오류

0

145

2

애플리케이션의 JPA 리턴과 도메인 모델

0

123

2

애그리거트 루트의 하위 도메인들의 depth가 깊어질 때 문의

0

130

2

페이징 처리를 해야한다면 어떻게 해야할까요?

0

184

2

애그리거트의 repository

0

113

2

Domain Expert가 정확히 어떤 역할을 하는 사람인가요?

0

223

1

회원 애플리케이션 서비스 테스트 (1)

0

100

2

정적 팩토리 메서드 관련 질문드립니다!

0

101

2

spotbug + @NonNullApi 로만 Null 방어가 될까요?

0

125

2

required 포트에 관해서

0

85

2

혹시 다음 편은 언제쯤 오픈할까요?

0

159

2

domain 모듈에 entity를 정의한다고 했을때

0

89

2

여러 엔티티의 조합으로 리포트를 제공해야할 때

0

73

2

Member와 MemberDetail 엔티티를 나누는 기준에 대해

0

78

2