백기선(인프런 강의)/더 자바, 애플리케이션을 테스트하는 다양한 방법
Mock 객체 확인
레알윙
2020. 5. 29. 08:58
반응형
Mock 객체가 어떻게 사용됐는지 확인이 가능하다.
예시코드는 아래의 깃사이트에서 다운로드 받을 수 있으며
https://github.com/keesun/inflearn-the-java-test
캡쳐한 index를 다운받으면 된다.
Verifying exact number of invocations
javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#exact_verification
특정 메소드가 특정 매개변수로 몇번 호출 되었는지, 최소 한번은 호출됐는지, 전혀 호출되지 않았는지
예시코드
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import me.whiteship.inflearnthejavatest.domain.Member;
import me.whiteship.inflearnthejavatest.domain.Study;
import me.whiteship.inflearnthejavatest.member.MemberService;
@ExtendWith(MockitoExtension.class)
class StudyServiceTest {
@Mock MemberService memberService;
@Mock StudyRepository studyRepository;
@Test
void createNewStudy() {
StudyService studyService = new StudyService(memberService, studyRepository);
assertNotNull(studyService);
Member member = new Member();
member.setId(1L);
member.setEmail("rlawls1991@email.com");
Study study = new Study(10, "테스트");
when(memberService.findById(1L)).thenReturn(Optional.of(member));
when(studyRepository.save(study)).thenReturn(study);
studyService.createNewStudy(1L, study);
assertEquals(member, study.getOwner());
verify(memberService, times(1)).notify(study);
}
}
위와같이 호출을 하게 된다면 오류가 발생할 것이다.
Wanted but not invoked:
memberService.notify(
me.whiteship.inflearnthejavatest.domain.Study@6691490c
);
-> at me.whiteship.inflearnthejavatest.study.StudyServiceTest.createNewStudy(StudyServiceTest.java:43)
However, there was exactly 1 interaction with this mock:
memberService.findById(1L);
-> at me.whiteship.inflearnthejavatest.study.StudyService.createNewStudy(StudyService.java:23)
바로 도메인을 호출아지 않았다는 말인데 찾을 수 있게 수정을 해야 한다.
아래와 같이 return값을 설정해주면 mock객체가 찾을 수 있다.
public class StudyService {
private final MemberService memberService;
private final StudyRepository repository;
public StudyService(MemberService memberService, StudyRepository repository) {
assert memberService != null;
assert repository != null;
this.memberService = memberService;
this.repository = repository;
}
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 = repository.save(study);
memberService.notify(study);
return newStudy;
}
}
Verification in order
어떤 순서대로 호출했는지
Verification with timeout
https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#verification_timeout
특정 시간 이내에 호출됐는지
Finding redundant invocations
특정 싯점 이후에 아무 일도 벌어지지 않았는지
전체 예시
@ExtendWith(MockitoExtension.class)
class StudyServiceTest {
@Mock MemberService memberService;
@Mock StudyRepository studyRepository;
@Test
void createNewStudy() {
StudyService studyService = new StudyService(memberService, studyRepository);
assertNotNull(studyService);
Member member = new Member();
member.setId(1L);
member.setEmail("rlawls1991@email.com");
Study study = new Study(10, "테스트");
when(memberService.findById(1L)).thenReturn(Optional.of(member));
when(studyRepository.save(study)).thenReturn(study);
studyService.createNewStudy(1L, study);
assertEquals(member, study.getOwner());
verify(memberService, times(1)).notify(study);
verify(memberService, times(1)).notify(member);
verify(memberService, never()).validate(any());
InOrder inOrder = Mockito.inOrder(memberService);
inOrder.verify(memberService).notify(study);
//verifyNoMoreInteractions(memberService);
inOrder.verify(memberService).notify(member);
}
}
반응형