야미의 개발

[Spring/SpringBoot] Mock 사용해보기(1) - Mockito란? 본문

스프링/웹 개발

[Spring/SpringBoot] Mock 사용해보기(1) - Mockito란?

채야미 2024. 6. 12. 15:39

테스트 코드를 작성하면서 Mock을 사용했다.

문제는 더 이상 검색으로 돌려막기가 불가능한 것... 

이참에 Mock에 대해 한번 정리해 보았다.

 

 

 

Mock객체란?

모의 객체(Mock Object)란 주로 객체 지향 프로그래밍으로 개발한 프로그램을 테스트 할 경우 테스트를 수행할 모듈과 연결되는 외부의 다른 서비스나 모듈들을 실제 사용하는 모듈을 사용하지 않고 실제의 모듈을 "흉내"내는 "가짜" 모듈을 작성하여 테스트의 효용성을 높이는데 사용하는 객체이다. 사용자 인터페이스(UI)나 데이터베이스 테스트 등과 같이 자동화된 테스트를 수행하기 어려운 때 널리 사용된다.

- 위키백과-

 

따라서 mock은 테스트의 효율성을 높이기 위한 객체이다.

예를 들어 컨트롤러 테스트에서 서비스의 메소드를 의존하게 되는 경우,

서비스의 특정 동작을 Mocking 처리하여 컨트롤러의 코드만 테스트할 수 있다.

 

 

Test Double

한편 이러한 테스트를 목적으로 실제 대신 사용되는 가짜 객체들은 

모두 Test Double 이라고 한다

 

 

 

더미 객체 (Dummy Object)

Dummy Object는 전달되지만 실제로는 사용되지 않는다. 인자로만 전달되고 동작하지 않고 코드의 형태를 유지하기 위해 필요

예시 : 데이터 베이스 연결이 필요하지만 실제로는 사용하지 않는 메서드에서 더미 객체로 데이터베이스 연결을 하는 경우

 

 

스텁 (Stub)

Stub은 테스트 중 호출된 경우에 대해 미리 만들어진 결과물을 응답하게 한다. 반환값을 고정하는 것.
보통 테스트를 위해 만들어지며 테스트 이외에 사용되지 않는다.

 

예시 : 외부 서비스의 응답을 위해서 호출했을 때 반환하는 데이터를 지정

 

 

가짜 객체 (Fake Object)

Fake Object는 실제로 동작하는 객체. 실제 시스템의 동작을 따라하지만 간소화된 로직을 사용한다.
실제 프로덕션 환경에 적합하지 않지만 지름길의 역할을 한다.

 

예시 : 인메모리 데이터 베이스
실제 프로덕션 환경에서는 다른 DB를 사용하지만 test에서는 H2를 사용하는 경우

 

 

모의 (Mock)

Mock은 호출했을 때 사전에 정의된 명세대로의 결과를 돌려주도록 미리 프로그래밍한다.

동작을 검증하기 위해 사용하며, 호출된 메서드와 인자를 기록해 호출여부를 검증하는 것이다.

예상치 못한 호출이 있을 경우 예외를 던질 수 있으며, 모든 호출이 예상된 것이었는지 확인할 수 있다.

 

 

스파이 (Spy)

Spy는 그들이 어떻게 호출되었는지에 따라 일부 정보를 기록하는 스텁입니다.
주로 어떤 동작이 이루어졌는지 검증하는 용도로 사용됩니다.

 

 

한편 자바 진영에서 주로 사용하는 Mock을 위한 툴은

Spring Boot Test, Mockito 등이 있다.

 

 

Mockito 알아보기 

Mockito는 자바에서 단위테스트를 하기 위해 Mock을 만들어주는 프레임워크다.
Mock이 필요한 테스트에 직관적으로 사용할 수 있도록 만들어졌다.

 

공식문서 번역본을 보면 아래와 같다

 

  • 간단한 사용법 : stub, use, verify
  • mock() or spy()을 사용해서 Mock들을 생성할 수 있습니다.
  • 다음을 통해 stub을 할 수 있습니다.
    • Mockito.when(mock.action()).thenReturn(true)
    • BDDMockito.given(mock.action()).willReturn(true)

      여기서 BDD는 Behavior-Driven Development의 약자로 행위 주도 개발을 말한다. 테스트 대상의 상태의 변화를 테스트하는 것이고, 시나리오를 기반으로 테스트하는 패턴을 권장한다. / given, when, then 형식으로 작성 가능
  • Mock의 응답을 개인화 하거나 지정할 수 있습니다.
    응답을 개인화 한다는건 테스트 시나리오에 맞게 모의 객체의 행동을 원하는대로 설정할 수 있는 것을 의미하는 거같다. Mockito는 고정된 응답과 동적인 응답 둘다 제공하기 때문이다.
  • 다음을 통해 제대로 동작하는지 확인(verification)할 수 있습니다.
    • Mockito.verify(mock).action()
    • BDDMockito.then(mock).should().action()
      한편 verify 메소드는 호출 여부만을 검증하는 것이다
  • @Mock, @Spy, @Captor or @InjectMocks과 같은 Annotation을 사용할 수 있습니다.
  • JUnit first class support via the runner MockitoJUnitRunner and the now favored rule MockitoJUnit.rule()
    Junit에서 MockitoJUnitRunner와 MockitoJUnit.rule()을 통해서 모의 객체를 쉽게 관리할 수 있다. 그리고 이 두개는 클래스에서 Mockito를 초기화하고 관리한다

 

Mockito 간단하게 사용하는 법

https://github.com/mockito/mockito/wiki/Mockito-features-in-Korean

 

Mockito features in Korean

Most popular Mocking framework for unit tests written in Java - mockito/mockito

github.com

아주 기초적인 mock의 사용법이 정리되어있지만, 솔직히 프로젝트 test 작성하는데는 큰 도움은 안되는거같으니 궁금하다면 공식문서를 읽는 것이 좋겠다.

 

다음글에서부터는 구체적인 Mock에 사용되는 것들을 살펴보고자 한다

 

 

 

 

참고

https://github.com/mockito/mockito/wiki/Mockito-features-in-Korean

 

Mockito features in Korean

Most popular Mocking framework for unit tests written in Java - mockito/mockito

github.com

 

 

https://charming-kyu.tistory.com/41

 

typescript로 배우는 stub, mock, spy의 차이점

mock은 stub과 다르다. 저는 테스트 코드를 작성 시 mock과 stub의 차이를 생각하지 않고 써왔습니다. 최근 마틴 파울러의 블로그에서 Mocks Aren't Stubs 라는 글을 발견했습니다. Mocks Aren't Stubs Explaining th

charming-kyu.tistory.com

 

Comments