일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- g1gc
- ansible
- Algorithm
- For
- 자료형
- Class
- While
- If
- Java
- 기초
- 연산자
- datastructure
- Kotlin
- zgc
- programmers
- UserDetails
- SpringBoot Initializr
- quicksort
- JavaScript
- JPA
- MergeSort
- redis
- C++
- IAC
- jvm
- Spring Security
- Fluent-bit
- datatype
- lambda
- Sprint Security
- Today
- Total
뭐라도 끄적이는 BLOG
Mockito 사용법 본문
Mock객체 만들기
MemberService와 StudyRepository를 이용해서 StudyRepository를 생성해야 하는것을 가정으로 하겠습니다.
Mockito.mock()메소드로 만드는 방법
@Test
void createStudyServiceForMockMethod() {
MemberService memberService = mock(MemberService.class);
StudyRepository repository = mock(StudyRepository.class);
StudyService studyService = new StudyService(memberService, repository);
assertNotNull(studyService);
}
@Mock Annotaiton
@ExtendWith(MockitoExtension.class)
public class StudyServiceTest {
@Mock
MemberService memberServiceMock;
@Mock
StudyRepository repositoryMock;
}
@Mock Annotation으로 생성한다면 MockitoExtension을 ExtendWith로 추가해 주어야 사용할 수 있습니다. Mock객체를 해당 테스트 클래스 모든 곳에서 사용한다면 좋은 방법입니다.
매개변수의 @Mock Annotation
@Test
void createStudyServiceForMethodParam(@Mock MemberService memberServiceMockInParam,
@Mock StudyRepository repositoryMockInParam){
StudyService studyService = new StudyService(memberServiceMockInParam, repositoryMockInParam);
assertNotNull(studyService);
}
매개변수에서 @Mock을 이용해서 생성할 수 있습니다. 위와 마찬가지로 MocktoExtension을 추가해야 합니다.
Mock객체의 기본 행동
Mock이 만들어 지면 바로 사용은 가능합니다. 하지만 말그대로 Mock이기 때문에 아무런 행동을 하지 않습니다. 이러한 행동은 다음과 같습니다.
- 리턴 값이 있으면 null을 리턴(Optional Type은 Optional.empty)
- Primitive 타입의 리턴은 기본 Primitive 값 (int = 0, boolean = false 등)
- Collection은 비어있는 Collection
- void return method는 아무런 일도 발생하지 않는다.
Mockito는 이렇듯 아무것도 하지않는 것들을 만든뒤 사용자가 테스트에서 직접 어떻게 행동해야 하는지 정의할 수 있습니다.
Mockito 객체 Stubbing
when
리턴 값이 있는 메소드의 경우 Mockito.when을 이용합니다.
when(memberServiceMock.findById(1L)).thenReturn(Optional.of(member));
memberService를 Mock으로 생성한 memberServiceMock의 findById메소드에 1L이라는 값을 넣으면 Optional.of(member)를 리턴한다라는 것을 명시해 줍니다. 1L이라는 특정한 값을 넣을 수도 있지만 any()라는 메소드를 이용해 어느값이 들어오던지 동작을 한다는 것등을 명시할 수 있습니다.
doThrow
리턴 값이 없는 경우 Mockito.doThrow를 사용합니다.
doThrow(new IllegalArgumentException())
.when(memberServiceMock).validate(1L);
이경우 memberServiceMock의 validate메소드에 1L이라는 값이 들어오면 IllegalArgumentException예외가 발생하는 경우를 나타낸 것입니다.
verify
Mock객체에서 실행되는 메소드를 확인하는 방법입니다. 다음은 MemberServic에 있는 한 메소드입니다.
public Study createNewStudy(Long memberId, Study study){
Optional<Member> member = memberService.findById(memberId);
study.setOwner(member.orElseThrow(() -> new IllegalArgumentException("Member doesn't exist for id:" + memberId)));
Study newStudy = studyRepository.save(study);
memberService.notify(newStudy);
memberService.notify(member.get());
return newStudy;
}
memberService가 createNewStudy를 호출했을때 어떤 메소드들이 실행되었는지 확인할 때 verify를 사용합니다.
studyService.createNewStudy(1L, study);
verify(memberServiceMock, times(1)).notify(study);
verify(memberServiceMock, times(1)).notify(member);
verify로 memberServiceMock에서 notify(Study)가 1회 호출되었고 notify(Member)가 1회 호출되었다 라는 것을 확인할 수 있습니다.
InOrder
위에서 확인한 메소드들의 호출 순서가 중요할 수도 있습니다. 이때 사용하는 것이 InOrder입니다.
studyService.createNewStudy(1L, study);
InOrder inOrder = inOrder(memberServiceMock);
inOrder.verify(memberServiceMock).notify(study);
inOrder.verify(memberServiceMock).notify(member);
verifyNoMoreInteractions(memberServiceMock);
notify(Study)가 먼저 호출된뒤 notify(Member)가 호출되었다는 것을 확인해 줍니다.
추가적으로 verifyNoMoreInteractions는 위 메소드 이후 아무것도 행동하지 않는다는 것을 확인해 줍니다.
BDDStyle
BDD Style에서 기본이되는 Given / When / Then을 BDDMockito에서 사용할 수 있습니다.
@Test
void startBDDStyle(){
//Given
Study study = new Study("test", 10);
Member member = new Member();
member.setEmail("delusidiot@gmail.com");
member.setId(1L);
BDDMockito.given(memberServiceMock.findById(1L)).willReturn(Optional.of(member));
BDDMockito.given(repositoryMock.save(study)).willReturn(study);
StudyService studyService = new StudyService(memberServiceMock, repositoryMock);
//When
studyService.createNewStudy(1L, study);
//Then
BDDMockito.then(memberServiceMock).should(times(1)).notify(study);
BDDMockito.then(memberServiceMock).should(times(1)).notify(member);
BDDMockito.then(memberServiceMock).shouldHaveNoInteractions();
}
Mockito에서 사용되었던 when메소드는 given으로 변경되었으며 리턴 결과를 알려주는 thenReturn도 willReturn으로 변경되었습니다. 그리고 verify도 then으로 변경된것을 볼 수 있습니다. 이렇게 given / when / then에 맞추어 BDD Style로 테스트를 작성할 수 있습니다.
참고자료
'Java > Mockito' 카테고리의 다른 글
Mockito 소개 (0) | 2021.12.06 |
---|