Mock 이란?

김멉덥·2022년 10월 9일
3

기술면접 공부

목록 보기
4/8
post-thumbnail

Mock 이란 ?

  • Mock은 한글로 "모의, 가짜의"라는 뜻
  • 실제 객체를 만들기엔 비용과 시간이 많이 들거나 의존성이 길게 걸쳐져 있어 제대로 구현하기 어려울 경우, 가짜 객체를 만들어 사용하는데 이것을 Mock이라 한다.
  • 즉, Mock은 테스트할 때 필요한 실제 객체와 동일한 모의 객체를 만들어 테스트의 효용성을 높이기 위해 사용한다.
  • WebApplicationContext를 로드하며 내장된 서블릿 컨테이너가 아닌 Mock 서블릿을 제공한다.
  • 별도로 지정하지 않으면 기본값은 Mock 서블릿을 로드하여 구동하게 된다.
  • @AutoConfigureMockMvc 어노테이션을 함께 사용하면 별다른 설정 없이 간편하게 MockMvc를 사용한 테스트를 진행할 수 있다.

Mock 객체는 언제 필요한가?

  1. 테스트 작성을 위한 환경 구축이 어려운 경우
    • 환경 구축을 위한 작업 시간이 많이 필요할 때
      (DB, 웹서버, FTP서버 등)
    • 특정 모듈을 갖고 있지 않아서 테스트 환경을 구축하지 못할 때
    • 타 부서와의 협의나 정책이 필요할 때
  2. 테스트가 특정 경우나 순간에 의존적인 경우
  3. 테스트 시간이 오래 걸리는 경우
  4. 개인 PC의 성능이나 서버의 성능문제로 오래 걸릴수 있는 경우 시간을 단축하기 위해

Mock에 대한 기본적인 분류

Mock에도 종류가 있는데, 이를 테스트 더블(Test Double) 이라 한다.

⇒ Mock Object를 이용한 테스트만 행위 기반 테스트이고, 나머지는 전부 상태 기반의 테스트이다.

테스트 더블이란 ?

  • 테스트를 진행하기 어려운 경우 이를 대신해 테스트를 진행할 수 있도록 만들어주는 객체
  • Mock객체와 유사한 의미를 가지며 테스트 더블Mock 보다 상위 의미로 사용

1. 더미 객체

  • 단순히 인스턴스화 될 수 있는 수준으로만 객체를 구현해놓은 것
  • 객체의 기능은 사용하지 않고 객체 자체로만 테스트를 진행할 수 있을 때 사용

2. 테스트 스텁

  • 더미 객체보다 좀 더 구현된 객체로 더미 객체가 실제로 동작하는 것처럼 보이게 만든 객체
  • 객체의 특정 상태를 가정해서 만들어 특정 값을 리턴하거나 특정 메시지를 출력하는 작업 진행
  • 테스트 스텁과, 더미의 차이점
    • 단지 인스턴스화될 수 있는 객체 수준이면 더미
    • 인스턴스화된 객체가 특정 상태나 모습을 대표하면 스텁
    • 마치, 실제 로직이 구현된 것처럼 보이는데, 그렇게 만들어진 객체를 페이크 객체

3. 페이크 객체

  • 여러 상태를 대표할 수 있도록 구현된 객체로 실제 로직이 구현된 것처럼 보이게 함
  • 페이크 객체를 만드는 복잡도로 인해서 시간이 많이 걸릴 경우 적절한 수준에서 구현하거나, Mock 프레임 워크를 사용해야한다.
  • 테스트 스텁과 페이크의 차이점
    • 스텁 은 하나의 인스턴스를 대표하는 데 주로 사용
    • 페이크 는 여러 개의 인스턴스를 대표할 수 있는 경우이거나,
      좀더 복잡한 구현이 들어가 있는 객체를 지칭할 때 주로 사용

4. 테스트 스파이

  • 테스트에 사용되는 객체, 메소드의 사용 여부 및 정상 호출 여부를 기록하고 이를 요청 시 알려준다.
    • 테스트 더블로 구현된 객체에 자기 자신이 호출 되었을 때, 확인이 필요한 부분을 기록하도록 구현.
  • 보통은 호출 여부를 몰래 감시해서 기록했다가, 나중에 요청이 들어오면 해당 기록 정보를 전달해준다.
  • 테스트 스파이는 특수한 경우를 제외하고는 잘 쓰이지 않으며 보통 Mock 프레임워크에서 기본적으로 기능이 제공된다.

5. Mock 객체

  • 행위를 검증하기 위해 사용되는 객체
  • 수동으로 만들 수도 있고 프레임워크를 통해 만들 수 있습니다.
  • 일반적인 테스트 더블은 상태(state)를 기반으로 테스트 케이스를 작성
    Mock 객체는 행위(behavior)를 기반으로 테스트 케이스를 작성

Mock 사용 시 유의사항

  1. Mock 프레임워크가 정말 필요한지 확인합니다.
  2. Mock을 사용하는 경우 테스트 케이스 유지에 복잡성이 더해지기 때문에 Mock이 없는 의존성 적은 구조로 프로그래밍합니다.
  3. Mock 객체는 가짜 객체일 뿐이라 실제 객체로 작동을 했을 때 작동하지 않을 수 있습니다.

Mock 프레임워크

  • 동적으로 Mock 객체를 만들어 주는 프레임워크이며, 사용시 아래의 장점이 있다.
    • Mock 객체를 명시적으로 생성하지 않아도 된다.
    • 행위기반 테스트도 가능하다.

Mockito

Mockito framework site

  • 여러 종류의 Mock 프레임워크가 존재하지면 현재 간편한 사용법으로 빠르게 확산되고 있으며 상태 기반 테스트를 지원하는 프레임워크이다.
  • Mock을 쉽게 만들고 Mock의 행동을 정하는 stubbing, 정상적으로 작동하는지에 대한 verify 등 다양한 기능을 제공해주는 프레임워크이다.

MockMvc 메서드

  • 오늘 수업시간에 했던 MockMvc 코드
@SpringBootTest
@Transactional  // 이 테스트를 수행하며 생긴 DB 변동사항은 반영되지 않는다.
@AutoConfigureMockMvc
public class AppTests {

    @Autowired
    private MockMvc mvc;    // MockMvc == 호출기, 브라우저라고 생각하면 된다.
												    // 특정 요청을 발생시킴

    @Test
    @DisplayName("메인화면에서는 안녕이 나와야 한다.")
    void t1() throws Exception {
        // when (GET /)
        ResultActions resultActions = mvc
                .perform(get("/"))
                .andDo(print());    // 콘솔에 출력됨

        // then (안녕)
        resultActions
                .andExpect(status().is2xxSuccessful())
                .andExpect(handler().handlerType(HomeController.class))
                .andExpect(handler().methodName("main"))
                .andExpect(content().string(containsString("안녕")));  
								// HomeController에 있는 main메서드에서 최종적으로 "안녕"이 들어있는지 검증
    }
}
  1. perform()
    • 요청을 전송하는 역할
    • 결과로 ResultActions 객체를 받으며,
      ResultActions 객체는 리턴 값을 검증하고 확인할 수 있는 andExcpect() 메소드를 제공
  2. get("/")
    • HTTP 메소드를 결정 ( get(), post(), put(), delete() 중 여기서는 GET 요청)
    • 인자로는 경로를 보내준다.
  3. andExpect()
    • 응답을 검증하는 역할을 한다.

참고 자료

profile
데굴데굴

1개의 댓글

comment-user-thumbnail
2023년 12월 11일

정리글 감사합니다 잘읽고갑니다

답글 달기