뭐라도 끄적이는 BLOG

Mockito 사용법 본문

Java/Mockito

Mockito 사용법

Drawhale 2021. 12. 6. 20:10

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로 테스트를 작성할 수 있습니다.


참고자료

 

 

더 자바, 애플리케이션을 테스트하는 다양한 방법 - 인프런 | 강의

자바 프로그래밍 언어를 사용하고 있거나 공부하고 있는 학생 또는 개발자라면 반드시 알아야 하는 애플리케이션을 테스트하는 다양한 방법을 학습합니다., 그냥 개발자를 넘어 '더 나은 개발

www.inflearn.com

 

Mockito framework site

Intro Why How More Who Links Training Why drink it? Mockito is a mocking framework that tastes really good. It lets you write beautiful tests with a clean & simple API. Mockito doesn’t give you hangover because the tests are very readable and they produc

site.mockito.org

 

 

Behavior-driven development - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search Agile software development process In software engineering, behavior-driven development (BDD) is an agile software development process that encourages collaboration among developers, q

en.wikipedia.org

 

반응형

'Java > Mockito' 카테고리의 다른 글

Mockito 소개  (0) 2021.12.06