[더 자바, 애플리케이션을 테스트하는 다양한 방법] Mockito

Jimin Lim·2022년 6월 26일
0

Test Code

목록 보기
2/4
post-thumbnail

✅ Mockito

Mock: 진짜 객체와 비슷하게 동작하지만 프로그래머가 직접 그 객체의 행동을 관리하는 객체 (가짜 객체)
Mockito: Mock 객체를 쉽게 만들고 관리하고 검증할 수 있는 방법을 제공한다.

다음 세 가지만 안다면 Mock을 활용한 테스트를 쉽게 작성할 수 있다.

  1. Mock 객체 만드는 방법
  2. Mock이 어떻게 동작해야 하는지 관리
  3. Mock의 행동을 검증하는 방법

세 가지 위주로 살펴보도록 한다.

🔗 Mock 객체 만드는 방법

StudyService 클래스를 살펴보면 아래와 같이 다른 클래스들과 의존하고 있다. 따라서 인스턴스를 만드려고 한다면 MemberService, StudyRepository의 인스턴스가 필요하다.

이때, MemberService와 StudyRepository에 대해 Mocking이 필요하다.

Mock객체를 만드는 방법은 (1) 직접 mock 객체 생성, (2) Mock 애노테이션 사용 이 있다.

(1) 직접 mock 객체 생성

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

(2) Mock 애노테이션 사용

//필드로 빼서 사용
@ExtendWith(MockitoExtension.class)
class StudyServiceTest {
    @Mock
    MemberService memberService;
    @Mock
    StudyRepository studyRepository;
    ...
} 
//메소드 매개변수로 사용
    @Test
    public void createStudyService(@Mock MemberService memberService,
                                   @Mock StudyRepository studyRepository) throws Exception{
        StudyService studyService = new StudyService(memberService,studyRepository);
        assertNotNull(studyService);
    }

🔗 Mock 객체 Stubbing

모든 Mock 객체의 행동은

  1. Null 리턴, Optional은 empty
  2. Primitive 타입은 기본 Primitive 값
  3. 콜렉션은 비어있는 콜렉션
  4. Void 메소드는 예외를 던지지 않고 아무런 일도 발생하지 않는다.

따라서, Mock객체를 호출할 때, 행동을 정의해줘야 한다.

(1) when

when(memberService.findById(1L)).thenReturn(Optional.of(member));
when(memberService.findById(2L)).thenThrow(new RuntimeException());

findById가 1L로 호출이 된다면, 특정 member가 호출되도록 정의한다. 혹은 예외를 던지도록 할 수 있다.

(2) doThrow

        doThrow(new IllegalArgumentException()).when(memberService).validate(1L);
        assertThrows(IllegalArgumentException.class, () -> {
            memberService.validate(1L);
        });

특정 매개변수를 받거나 호출된 경우, 예외를 발생시킬 수 있다. 또한 JUnit의 assertThrows를 통해 예외를 확인할 수 있다.

(3) 호출 횟수에 따라 다른 return 값 부여

        when(memberService.findById(any()))
                .thenReturn(Optional.of(member)) //member return
                .thenThrow(new RuntimeException()) //예외 반환
                .thenReturn(Optional.empty()); //empty 반환

🔗 Mock 행동 검증

        verify(memberService, times(1)).validate(any()); //1번 호출
        verify(memberService, never()).findById(any()); //한 번도 호출되지 않는다.

함수 호출 횟수를 검증할 수 있다.

✅ Mockito BDD 스타일 API

BDD: 애플리케이션이 어떻게 행동해야 하는지에 대한 공통된 이해를 구성하는 방법

행동을 정의할 때, Given(주어진 상황에) / When(특정 행위를 한다면) / Then(이러한 결과가 나올 것이다.)과 같이 구성할 수 있다.

앞서 정의한 메서드를 BDD로 정의할 수 있다.

(1) when -> given

when(memberService.findById(1L)).thenReturn(Optional.of(member));
given(memberService.findById(1L)).willReturn(Optional.of(member));

(2) verify -> then

verify(memberService, times(1)).validate(any());
then(memberService).should(times(1)).validate(any());
profile
💻 ☕️ 🏝 🍑 🍹 🏊‍♀️

0개의 댓글