Skip to content

Mock #
Find similar titles

Structured data

Category
Programming

Mock이란? #

실제 객체를 만들기엔 비용과 시간이 많이 들거나 의존성이 길게 걸쳐져 있어 제대로 구현하기 어려울 경우, 가짜 객체를 만들어 사용한다.

Mock 객체는 언제 필요한가? #

  • 테스트 작성을 위한 환경 구축이 어려운 경우
    • 환경 구축을 위한 작업 시간이 많이 필요한 경우에 Mock객체를 사용한다. (데이터베이스, 웹서버, 웹애플리케이션서버, FTP서버, 등)
    • 특정 모듈을 갖고 있지 않아서 테스트 환경을 구축하지 못할 때 또는 타 부서와의 협의나 정책이 필요한 경우에 사용한다.
  • 테스트가 특정 경우나 순간에 의존적인 경우
  • 테스트 시간이 오래 걸리는 경우
  • 개인 PC의 성능이나 서버의 성능문제로 오래 걸릴수 있는 경우 시간을 단축하기 위해 사용한다.

Mock에 대한 기본적인 분류 개념, 테스트 더블 #

1. 테스트 더블 #

  • 메스자로스(Gerard Mezaros)가 "xUnitText Patterns"에서 만들어낸 용어로 테스트를 진행하기 어려운 경우 이를 대신해 테스트를 진행 할 수 있도록 만들어주는 객체를 말한다. * Mock 객체와 유사한 의미를 가지며 테스트 더블이 좀더 상위 의미로 사용된다.

2. 더미객체(Dummy Object) #

  • 단순히 인스턴스화될 수 있는 수준으로만 객체를 구현한다.
  • 인스턴스화된 객체가 필요할 뿐 해당 객체의 기능까지는 필요하지 않은 경우에 사용한다.

3. 테스트 스텁(Test Stub) #

  • 더미 객체 보다 좀더 구현된 객체로 더미 객체가 마치 실제로 동작하는 것처럼 보이게 단들어 놓은 객체이다.
  • 객체의 특정 상태를 가정해서 만들어 특정 값을 리턴해 주거나 특정 메시지를 출력해 주는 작업을 한다.
  • 특정 상태를 가정해서 하드코딩된 형태이기 때문에 로직에 따른 값의 변경은 테스트 할 수 없다.

4. 페이크 객체(Fake Object) #

  • 여러 상태를 대표할 수 있도록 구현된 객체로 실제 로직이 구현된 것처럼 보이게 한다.
  • 실제로 DB에 접속해서 비교할 때와 동일한 모양이 보이도록 객체 내부에 구현 할 수 있다.
    • 테스트케이스 작성을 위해서 다른 객체들과의 의존성을 제거하기 위해 사용한다.
    • 페이크 객체를 만들 때 복잡도로 인해서 노력이 많이 들어 갈 경우 적절한 수준에서 구현하거나, Mock 프레임 워크를 사용한다.
    • 페이크 객체를 생성하기 위한 노력이 많이 필요한 경우 실제 객체를 가져와 테스트 한다.

5. 테스트 스파이(Test Spy) #

  • 테스트에 사용되는 객체, 메소드의 사용 여부 및 정상 호출 여부를 기록하고 요청시 알려준다.
  • 테스트 더블로 구현된 객체에 자기 자신이 호출 되었을 때 확인이 필요한 부분을 기록하도록 구현한다.
  • 특정 테스트 메서드가 몇번 호출 되었는지 필요한 경우 전역 변수로 카운트를 설정하고 특정 테스트 메서드에 카운트를 올리는 부분을 추가한 후 이 카운트를 가져오는 메서드를 추가한다.
  • 아주 특수한 경우를 제외하고는 잘 쓰이지 않으며 보통 Mock 프레임워크에서 기본적으로 기능을 제공하므로 Mock을 사용한다.
  • 특정 메소드가 호출 되었을 때 또 다른 메서드가 실행이 되어야 한다와 같은 행위 기반 테스트가 필요한 경우 사용한다.

6. Mock 객체(Mock Object) #

  • 행위를 검증하기 위해 사용되는 객체를 지칭하며 수동으로 만들 수도 있고 프레임워크를 통해 만들 수 있다.
  • 행위 기반 테스트는 복잡도나 정확성등 작성하기 어려운 부분이 많기 때문에 상태 기반 테스트가 가능하다면 만들지 않는다.
  • Mock 객체는 테스트 더블 하위객체로 써의 좁은 의미와 테스트 더블을 포함한 넓은 의미 2가지로 사용 될 수 있다.

Mock 프레임워크 #

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

1. EasyMock #

  • 가장 오래된 Mock프레임워크이며, 오픈소스로 탐 프리스가 만들었다.
  • 홈페이지는 http://easymock.org 이다.
  • 일반적으로 Mock 프레임워크는 인터페이스를 통해 객체를 생성하는데 EasyMock Class Extention이라는 기능을 통해 구현 클래스를 통하여 객체를 생성하도록 지원한다.
  • 기본적으로 4단계를 통하여 동작하며 각 단계는 생략될 수 있다.
    • CreateMock : 인터페이스에 해당하는 Mock 객체를 생성한다.
    • Record : Mock 객체 메소드의 예상되는 동작을 녹화한다.
    • Replay : 예정된 상태로 재생한다.
      • Verify : 예정된 행위가 발생했는지 검증한다.
      • 녹화, 재생이라는 개념은 처음 접하는 사람들에게는 어려운 개념이다. 그러나, 가장 오래된 프레임워크라서 과거에 많이 사용되었기 때문에 읽을 수 있을 정도는 배워두는 것이 좋다.

2. jMock #

  • 스티프 프리만, 냇 프라이스가 만든 프레임 워크로 테스트 표현의 확대와 가독성이 좋다.
    • 홈페이지는 http://www.jmock.org 이다.
    • 특징은 아래와 같다.
      • 연쇄호출(call-chain) : 동일한 객체에 여러 개의 메세지를 보낼 수 있다. void로 선언된 메서드도 플로우를 만들어서 순차 호출 할 수 있다.
  • 전용 Macher 사용 : 기본적으로 Hamcrest Macher 라이브러리를 사용한다.
  • 기본적으로 아래의 4단계로 진행된다.
    • CreateMock : 인터페이스에 해당하는 Mock 객체를 생성한다.
    • Expect : Mock 객체의 예상되는 동작을 미리 지정한다.
    • Excercise : 테스트 메소드 내에서 Mock 객체를 사용한다.
    • Verify : 예상한 행위가 발생했는지 검증한다. 사용자가 작성하지 않고 프레임워크가 자동으로 판단한다.

3. Mockito #

  • 역사는 오래되지 않았지만 간편한 사용법으로 빠르게 확산되고 있으며 상태 기반 테스트를 지원한다.
    • 홈페이지는 https://code.google.com/p/mockito/ 이다.
    • 특징은 아래와 같다.
      • 사용법이 단순하다.
      • call("getName")처럼 이름이 호출하지 않는다.
      • 읽기 어려운 anonymous inner클래스를 사용하지 않는다.
      • 리펙토링이 쉽다.
      • 작성이 어렵지 않아 테스트 자체에 집중할 수 있다.
      • 테스트 스텁을 만드는 것과 검증을 분리한다.
      • Mock 만드는 방법을 단일화 했다.
      • 테스트 스텁을 만들기 쉽다.
      • API가 간단하다.
      • 실패 시에 발생하는 스택 트레이스가 깔끔하다.
    • 아래의 4단계로 진행된다.
      • CreateMock : 인터페이스에 해당되는 Mock 객체를 만든다.
      • Stub : 테스트에 필요한 Mock 객체의 동작을 지정한다.
      • Excercise : 테스트 메소드 내에서 Mock 객체를 사용한다.
      • Verify : 메서드가 예상되로 호출되었는지 검증한다.

4. Mock 사용시 유의사항 #

  • Mock 프레임워크가 정말 필요한지 확인한다.
  • Mock을 사용하는 경우 테스트 케이스 유지에 복잡성이 더해지기 때문에 Mock이 없는 의존성 적은 구조로 프로그래밍 한다.
  • 어떤 Mock 프레임워크를 사용하느냐는 핵심 문제가 아니다.
    • 어떤 프레임워크를 사용하느냐에 따라 테스트 케이스 작성에 커다란 영향이 미치지 않는다. 단지 익숙해지기 까지 시간이 필요할 뿐이다.
  • Mock 객체는 Mock 일 뿐이다.
  • 실제 객체로 작동을 해보았을 때 잘 작동하지 않을 수도 있다. Mock 객체는 흉내를 내는 객체이기 때문이다.

Incoming Links #

Related Data Sciences #

Suggested Pages #

0.0.1_20140628_0