Java&Web

[JUnit] Mockito를 이용한 단위 테스트

프로그래민 2021. 2. 2. 00:33
반응형

Mockito란?

Mockito란 단위 테스트를 위한 Java Mocking Framework이다. JUnit에서 가짜 객체인 Mock을 생성해주고 관리하고 검증할 수 있도록 지원해주는 Framework이다. 구현체가 아직 없는 경우나 구현체가 있더라도 특정 단위만 테스트하고 싶을 경우 사용할 수 있도록 적절한 환경을 제공해준다.

 

Mock 객체란?

Mockito에서 Mock 객체를 제공해준다고 위에서 언급이 되었는데, Mock 객체란 다음과 같다. Mock 객체란 개발한 프로그램을 테스트할 때 테스트를 수행할 모듈과 연결되는 외부의 다른 모듈을 흉내 내는 가짜 모듈을 생성하여 테스트의 효율성을 높이는 데 사용하는 객체이다.

다음과 같은 예가 있다고 가정해보자.

Comment의 일부

위와 같은 클래스들이 있는 상황에서 CommentService의 registerComment 메소드를 테스트하는 상황이다. 이 상황에서 테스트하고자 하는 바는 registerComment 메소드가 적절한 인자와 함께 호출이 되어 CommentDao의 insertComment 까지를 정상적으로 호출하는지가 관심사이다. 즉, registerComment 테스트의 주된 관심사는 insertComment가 어떻게 구현되어서 어떻게 실행이 돼있는지가 아니라 insertComment가 제대로 호출이 되었는지가 테스트의 주된 관심사이다.

Mock 객체는 이러한 상황에서 CommentDao를 가짜 모듈로써 사용할 수 있도록 도와준다. 즉, CommentDao를 Mock 객체로 사용하여 insertComment가 정상적인 리턴 값을 던져주도록 도와주고, 이로써 registerComment 메소드의 단위 테스트에서 오로지 registerComment 메소드에 집중할 수 있도록 해준다.

 

Mockito 메소드 종류

대표적으로 다음과 같은 Mockito 메소드가 있다.

  • mock() : Mock 객체를 생성해주는 메소드
    ex) Person p = mock(Person.class); -> Person을 Mock 객체로 생성

  • when() : Mock 객체의 메소드 반환 값을 지정해주는 메소드
    ex) when(p.getName()).thenReturn("min"); -> p.getName()이 호출되었을 때 min을 반환하도록 지정

  • verify() : Mock 객체에서 메소드가 호출 되었는지를 확인해주는 메소드
    ex) verify(p).getName(); -> p.getName()이 호출되었는지를 확인

  • times() : 지정한 횟수 만큼 Mock 객체의 메소드가 호출 되었는지를 확인해주는 메소드
    ex) verify(p, times(1)).getName(); -> p.getName()이 1번 호출되었는지를 확인

  • never() : Mock 객체의 메소드가 호출 안되었는지를 확인해주는 메소드

  • atLeast(), atMost() : Mock 객체의 메소드가 최소, 최대 지정 횟수 만큼 호출 되었는지를 확인해주는 메소드
     
  • timeOut() : Mock 객체의 메소드가 지정된 시간안에 호출되었는지를 확인해주는 메소드

 

Mockito 실습

spring-boot-starter-test 추가

spring-boot-starter-test 추가
spring-boot-starter-test에 포함되어 있는 mockito

Springboot + Maven 환경에서 spring-boot-starter-test dependency에 포함되어 있는 Mockito를 이용하여 환경을 구축하였다.

 

Mockito를 이용하여 Mock 객체 생성

CommentServiceTest.java

CommentService를 테스트 하기 위해 주된 관심사가 아닌 CommentDao와 CommentHistoryDao를 Mock 어노테이션을 이용하여 생성하고 CommentSerivce에 주입해주었다.

 

CommentService의 removeComment 메소드 테스트

CommentService의 removeComment 메소드
CommentServiceTest의 removeTest 메소드

CommentService의 removeComment를 테스트하기 위해 Mockito의 함수들을 이용하여 위와 같은 단위 테스트를 구성하였다. 

given절부터 보자면 commentId를 지정해주고, removeComment 함수안에서 호출될 commentDao.selectComment()를 위하여 when() 메소드를 사용하여 Mock객체인 Comment를 할당해주었다. 그 후 when절에서 주된 관심사인 removeComment를 호출해주었다. then절에선 CommentService의 removeComment가 호출되면 제대로 내부가 동작하는지 확인하기 위해 Mock 객체로 생성된 CommentDao와 CommentHistroyDao의 메소드를 verify() 메소드를 이용하여 확인해주었다. 

 

결과

CommentServiceTest의 removeTest 결과

Mockito를 이용하여 Mock 객체를 생성하고, 그것을 사용하여 단위 테스트한 결과 위와 같은 결과를 얻을 수 있었다. Mock 객체를 이용한 덕분에 단위테스트에서 주된 관심사인 CommentService의 removeComment에 만 집중할 수 있었고, 좀 더 직관적이고 간단하게 단위 테스트를 수행할 수 있었다.

 

출처
jdm.kr/blog/222
sun-22.tistory.com/93
www.crocus.co.kr/1556
site.mockito.org/
반응형