반응형
Spring boot와 JUnit5, Mockito를 사용해서 Service layer의 테스트 코드를 작성하는 방법을 찾아봤다. Mockito 라이브러리를 사용해서 연관된 Repository, Service 등은 Mock 객체로 만들고 진짜 테스트 하고 싶은 기능을 테스트 해보자.
https://www.baeldung.com/mockito-series 여기에 예제가 많이 있었다.
mock 객체로 만들어서 테스트 하기
@ExtendWith: Mockito를 사용하는 환경으로 설정한다.
@Mock: 클래스의 가짜 인스턴스를 만들어준다.
@InjectMocks: 클래스의 필요한 의존성을 Mock으로 자동으로 주입한 인스턴스를 만들어준다.
배운 것과 나의 생각
- Service를 테스트 할 때 중요한 점은 어떤 것을 테스트 할 것인지 생각하는 것이다. Service 단위 테스트이기 때문에 Service의 비즈니스 로직가 예상대로 실행되는지 검사하고, 다른 부분은 Mock으로 처리해야 한다.
- void 메서드를 테스트 할 때는 ArgumentCaptor와 verify를 사용해서 검증할 수 있다.
- 중복 테스트 코드 작성은 엄청 피곤하다. FIRST 규칙을 지키는 테스트 코드를 만들자.
- 입력 값을 만들기 위한 코드를 최대한 줄이자.
테스트 코드
@ExtendWith(MockitoExtension.class)
class MemberServiceTest {
@Mock
private MemberRepository memberRepository;
@Mock
private CardRepository cardRepository;
@Mock
private PasswordEncoder passwordEncoder;
@InjectMocks
private MemberService memberService;
@Test
public void Given_MemberCreateRequest_When_Create_Then_SaveEntity() {
//given
MemberCreateRequest request =
new MemberCreateRequest("username", "password");
String encodedPassword = "encodedpassword";
//when
when(passwordEncoder.encode(anyString())).thenReturn(encodedPassword);
memberService.create(request);
ArgumentCaptor<Member> memberCaptor = ArgumentCaptor.forClass(Member.class);
verify(memberRepository).save(memberCaptor.capture());
Member savedMember = memberCaptor.getValue();
//then
assertThat(savedMember.getUsername()).isEqualTo(request.getUsername());
assertThat(savedMember.getPassword()).isEqualTo(encodedPassword);
}
@Test
public void Given_DuplicateUsernameMemberCreateRequest_When_Create_Then_ThrowDuplicateUsernameException() {
//given
MemberCreateRequest request =
new MemberCreateRequest("username", "password");
//when
when(memberRepository.save(Mockito.any(Member.class)))
.thenThrow(new DuplicateUsernameException());
Throwable throwable = catchThrowable(() -> memberService.create(request));
//then
assertThat(throwable).isInstanceOf(DuplicateUsernameException.class);
}
@Test
public void Given_Username_When_FindCards_Then_ReturnUserCardDtoList() {
//given
String username = "username";
List<Card> cards = List.of(
Card.builder()
.title("제목1")
.content("내용1")
.build(),
Card.builder()
.title("제목2")
.content("내용2")
.build()
);
//when
when(cardRepository.findByMember_Username(username)).thenReturn(cards);
List<CardResponse> cardResponses = memberService.findCards(username);
//then
assertThat(cardResponses)
.hasSize(cards.size())
.zipSatisfy(cards, (cardResponse, card) -> {
assertThat(cardResponse.getTitle()).isEqualTo(card.getTitle());
});
}
}
반응형
'Tool > Spring' 카테고리의 다른 글
[Spring boot] 외부 파일 저장소를 사용할 때 트랜잭션은 어떻게 관리해야 할까? (with. AWS S3) (2) | 2023.12.11 |
---|---|
[Spring boot] controller layer 테스트 코드 작성하기 (0) | 2023.12.04 |
[Spring boot] Dto 유효성 검사 테스트 코드 작성하기 (0) | 2023.12.03 |
[Spring boot] H2 데이터베이스에서 MySQL dialect 설정하기 (0) | 2023.12.01 |
[Spring boot] JUnit5 테스트 코드 작성하기 (0) | 2023.12.01 |