barded
[무물] 2-2. 계층별 단위테스트 - Service 본문
Service 계층의 단위 테스트 역할
Service 계층의 단위 테스트는 Repository를 Mock객체로 주입받은 후, Service를 호출하여 예상한 결과가 맞는지 확인하면 된다.
FromMeServiceTest
@ExtendWith(MockitoExtension.class)
class FromMeServiceTest {
@InjectMocks
FromMeService fromMeService;
@Mock
PostRepository postRepository;
@Mock
CommentRepository commentRepository;
@Mock
UserRepository userRepository;
@Mock
OptionRepository optionRepository;
@Mock
VoteRepository voteRepository;
@Mock
PostLikeRepository postLikeRepository;
@Test
@DisplayName("FromMe 피드")
public void getFromMeFeed() throws Exception {
//given
User user = User.builder().id(1L).username(USERNAME).build();
Post post = Post.builder().id(1L).content(POST).postType(PostType.FROM_ME).optionList(new ArrayList<>()).build();
Option option1 = Option.builder().id(1L).content("option1").build();
Option option2 = Option.builder().id(2L).content("option1").build();
Vote vote = Vote.builder().id(1L).user(user).option(option1).build();
PostLike postLike = PostLike.builder().id(1L).post(post).user(user).build();
post.addOption(option1);
post.addOption(option2);
PageRequest pageRequest = PageRequest.of(0, 10);
given(userRepository.findByUsername(USERNAME)).willReturn(Optional.of(user));
given(postRepository.findByUserId(user.getId(), PostType.FROM_ME, pageRequest)).willReturn(List.of(post));
given(voteRepository.findByUserIdAndOptionIdIn(user.getId(), post.getOptionList().stream().map(Option::getId).toList())).willReturn(Optional.of(vote));
given(postLikeRepository.existsByUserIdAndPostId(user.getId(), post.getId())).willReturn(true);
given(voteRepository.countAllByOptionIdIn(post.getOptionList().stream().map(Option::getId).toList())).willReturn(1L);
//when
UserDetailDto userDetailDto = new UserDetailDto(user.getId(), user.getUsername());
List<PostResponseDto> fromMeFeed = fromMeService.getFromMeFeed(userDetailDto, USERNAME, pageRequest);
//then
assertThat(fromMeFeed).hasSize(1);
assertThat(fromMeFeed.get(0).voted()).isEqualTo(1);
assertThat(fromMeFeed.get(0).liked()).isEqualTo(true);
}
}
Service 계층의 Annotation들
- @ExtendWith(MockitoExtension.class):
- 이 애노테이션은 Mockito를 사용하여 테스트에 필요한 목(mock) 객체를 초기화함. JUnit 5 환경에서 Mockito를 활용하기 위해 클래스 레벨에 선언함.
- @InjectMocks:
- 테스트 대상 클래스에 목 객체를 자동으로 주입함. 여기서는 FromMeService 클래스가 테스트 대상이므로, 해당 서비스에 필요한 의존성들이 목 객체로 주입됨.
- @Mock:
- Mock 객체를 생성함. PostRepository, CommentRepository, UserRepository, OptionRepository, VoteRepository, PostLikeRepository 등 테스트 과정에서 필요한 의존성들을 목으로 생성하여, 실제 데이터베이스나 외부 서비스와의 상호작용 없이 테스트를 진행할 수 있게 함.
- @Test:
- 테스트를 실행할 메소드임을 나타냄. 이 메소드 내에서 실제 테스트를 수행하게 됨.
- @DisplayName:
- 테스트 메소드의 이름이나 목적을 문자열로 명시함. 테스트 실행 결과 보고서에서 해당 테스트를 쉽게 식별할 수 있도록 함.
Service의 Given-When-Then
- given:
- 주어진 환경이나 상황을 설정함. 이 경우에는 테스트를 위해 필요한 사용자, 게시물, 투표, 좋아요 등의 객체를 생성하고, 이들 간의 관계를 정의함. 또한, BDDMockito의 given 메소드를 사용하여 특정 메소드 호출에 대한 반환값을 명시함으로써, 테스트 중에 해당 메소드가 호출될 때 원하는 값이 반환되도록 설정함.
- when:
- 실제로 테스트하고자 하는 조건이나 행위를 실행함. 이 경우에는 FromMeService의 getFromMeFeed 메소드를 호출하여, 주어진 사용자 이름과 페이지 요청 정보를 기반으로 "FromMe 피드"를 가져오는 로직을 실행함.
- then:
- when 절에서 실행한 행위의 결과를 검증함. 이는 테스트의 핵심 부분으로, 결과값이 기대한 바와 일치하는지 확인함. 여기서는 가져온 "FromMe 피드"의 크기가 1인지, 투표 여부가 1(투표함)인지, 좋아요 여부가 참인지를 검증하여, 서비스가 올바르게 작동하는지 확인함.
[무물] 2-1.계층별 단위테스트 - Repository
[무물] 2-3. 계층별 단위테스트 - Controller
[무물] 3-1. 통합테스트 MockMvc vs. WebTestClient vs. TestRestTemplate
'프로젝트 > 무물' 카테고리의 다른 글
[무물] 3-2. 통합테스트 (0) | 2024.06.06 |
---|---|
[무물] 3-1. 통합테스트 MockMvc vs. WebTestClient vs. TestRestTemplate (0) | 2024.06.06 |
[무물] 2-3. 계층별 단위테스트 - Controller (0) | 2024.06.06 |
[무물] 2-1.계층별 단위테스트 - Repository (0) | 2024.06.06 |
[무물] 1. 단위테스트 / 통합 테스트 란? (1) | 2024.06.06 |