Mockito 사용법

jaycee·2024년 2월 20일
post-thumbnail

Mockito란?

진짜 객체와 비슷하게 동작하지만 프로그래머가 직접 그 객체의 행동을 관리하는 객체.

테스트할 서비스 자체만 테스트하고, 서비스 이외의 부분은 mock으로 대체하여 본래 목적의 프로그램 테스트만 잘 동작하도록 설정한다.

mockito 문서보기: https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html

언제 사용하나?

1) 인터페이스만 있고 구현되어있지 않는 경우, 일반적으로 직접 그 내용을 구현해야하지만 mock을 사용하면 코드를 간략하게 작성할 수 있다.
2) 외부 연동과 같이 통제가 안되는 서비스를 테스트 코드에 사용해야 할 때

Mockito 사용하기 위해 알아둘 것

  • mock을 만드는 방법
  • mock이 어떻게 동작해야 하는지 관리하는 방법 (stubbing)
  • mock의 행동을 검증하는 방법

Mock 만드는 방법

mock을 사용하기 위해 가장 먼저 mock 객체를 만든다.

1. mock()을 직접 호출하는 방법

MemberService memberService = mock(MemeberService.class);
StudyRepository studyRepository = mock(StudyRepository.class);

2. @Mock 어노태이션을 이용하는 방법

//extend를 선언해주고
@ExtendWith(MockitoExtension.class)
class studyTest{

	//1) 직접 선언할 수도 있고
	@Mock MemberService memberService;

	@Mock StudyRepository studyRepository;

	//2) 또는 메소드 파라미터로 직접 넣어줄 수도 있다.
	@Test void createStudyService(@Mock MemberService memberService,
																@Mock StudyRepository studyRepository) {

		StudyService studyService = new StudyService(memberService, studyRepository);
		assertNotNull(studyService);

	}
}

Mock 객체 Stubbing (행동 정의)

모든 Mock 객체의 행동

  • null을 리턴한다. Optional 타입은 optional.empty 리턴한다.
  • primitive 타입은 기본 primitive값 (int는 0, boolean false)
  • 컬렉션은 비어있는 컬렉션
  • void 메소드는 예외를 던지지 ㅇ낳고 아무런 일도 발생하지 않는다.

subbing 하기

return subbing

  • 특정 파라미터를 입력받았을 때 지정한 값을 리턴할 수 있다.
  • 어떠한 파라미터를 입력받더라도 지정한 값을 리턴할 수 있다.
Member member = new member();
member.setId(1L);
member.setEmail("tester@email.com")

//1L로 검색 시에만 리턴하는 시키도록 stubbing하거나
when(memberService.findById(1L)).thenReturn(Optional.of(member));
//인자를 any로 입력 시 항상 같은 객체를 리턴 subbing
when(memberService.findById(any())).thenReturn(Optional.of(member));

Study study = new Study(10, "java");

//stubbing 된 member가 리턴된다.
studyService.createNewStudy(1L, study)

exception throwing stubbing

//when 메소드의 thenThrow를 사용하거나
when(memberService.findById(1L)).thenThrow(new RuntimeException());

//doThrow를 사용
doThrow(new IllegalArgumentException()).when(memberService).validate(1L);

consecutive calls stubbing

메소드가 동일한 매개변수로 여러 번 호출 될 때 각기 다르게 행동하도록 조작할 수 있다.

when(memberService.findById(any()))
				.thenReturn(optional.of(member))  //#1
				.thenThrow(new RuntimeException()) //#2
				.thenReturn(Optional.empty());  //#3


//#1 호출
when(memberService.findById(1L)).thenReturn(Optional.of(member));

//#2 호출
when(memberService.findById(1L)).thenReturn(Optional.of(member));

//#3 호출
when(memberService.findById(1L)).thenReturn(Optional.of(member));

Mock 실행됐는지 검증하기

//1번 notify가 1번 호출했는지 확인
verify(memberService, times(1)).notify(study))

//validate가 실행 안됐는지 확인
verify(memberService, never()).validate(any());

BDD 스타일로 작성하는 방법

💡 BDD - Behavior Driven Development

given, when, then형식으로 테스트를 할수 있도록 지원

@DisplayName("스터디가 생성되면 안내한다.")
@Test
void createStudy(){
	
	//given (기존 when은 BDD스타일의 when과 햇갈리므로 given으로 변경)
	when(memberService.findById(1L)).willReturn(Optional.of(member));
	given(memberService.findById(1L)).willReturn(optional.of(member));
	
	//when
	studyService.createStudy(1L, study)
	
	//then (verify를 then으로 변경)
	then(memberService).should(times(1)).notify(study);

}

출처: 백기선님 인프런 강의 "더 자바, 애플리케이션을 테스트하는 다양한 방법"를 수강 후 정리한 내용임
https://www.inflearn.com/course/the-java-application-test/dashboard

profile
오늘도 하나 배웠다.

0개의 댓글