Mock에 대한 개념과 프레임워크를 알 수 있다.

Mock 이란?

  • 일반적인 의미로 조각하기 쉬운 재료를 이용해 추후 만들어질 제품의 외양을 흉내낸 모조품을 말한다.
  • 개발에 있어서는 실제 모듈에서 사용하는 객체와 비슷하게 만든 가짜 객체를 말한다.
  • 실제 객체를 만들기엔 비용과 시간이 많이 들거나 의존성이 길게 걸쳐져 있어 제대로 구현하기 어려울 경우, 가짜 객체를 만들어 사용한다.
  • 테스트 더블의 한 종류이다.

Mock 객체는 언제 필요할까?

  • 테스트 작성을 위한 환경 구축이 어려운 경우
    • 환경 구축을 위한 작업 시간이 많이 필요한 경우 (데이터베이스, 웹서버, FTP서버 등)
    • 필요한 특정 모듈이 아직 개발이 안 된 경우
  • 테스트가 특정 경우나 순간에 의존적인 경우
  • 테스트 시간이 오래 걸리는 경우
    • 개인 PC의 성능이나 서버의 성능문제로 오래 걸릴 수 있는 경우 시간을 단축하기 위해 사용

Mock 객체의 특징

  • 상태 기반 테스트와 행위 기반 테스트로 분류된다.
    • 상태 기반 테스트(state base test)
      • 객체가 특정 시점에 자신만의 상태를 갖는 특징에 기반한 테스트 방식이다.
      • 객체.setName(‘doy’) 메소드를 호출했으면, getName() 메소드로 확인해보는 방법이다.
    • 행위 기반 테스트(behavior base test)
      • 올바른 로직 수행에 대한 판단의 근거로, 특정한 동작의 수행 여부를 이용한다.
      • 보통은 메소드의 리턴값이 없거나(void 메소드), 리턴값을 확인하는 것만으로는 예상대로 동작했음을 보증하기 어려운 경우에 사용한다.
  • 행위를 검증하기 위해 사용되는 객체를 지칭하며 수동으로 만들 수도 있고 프레임워크를 통해 만들 수 있다.
  • 행위 기반 테스트는 복잡도나 정확성 등 작성하기 어려운 부분이 많기 때문에 상태 기반 테스트가 가능하다면 만들지 않는다.

Mock 프레임워크

Mock 객체를 명시적으로 생성하지 않아도 되므로 테스트 코드 작성 시 대부분 프레임워크를 사용한다.

1. EasyMock

  • 특징
    • 가장 오래된 Mock 프레임워크이며, 오픈소스로 탐 프리스가 만들었다.
    • 일반적으로 Mock 프레임워크는 인터페이스를 통해 객체를 생성하는데 EasyMock Class Extension이라는 기능을 통해 구현 클래스를 통하여 객체를 생성하도록 지원한다.
  • 사용
    • CreateMock
      • 인터페이스에 해당하는 Mock 객체를 생성한다.
    • Record
      • Mock 객체 메소드의 예상되는 동작을 녹화한다.
    • Replay
      • 예정된 상태로 재생한다.
    • Verify
      • 예정된 행위가 발생했는지 검증한다.

2. jMock

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

3. Mockito

  • 특징
    • 역사는 오래되지 않았지만 간편한 사용법으로 빠르게 확산되고 있으며 상태 기반 테스트를 지원한다.
    • 작성이 어렵지 않아 테스트 자체에 집중할 수 있다.
    • 테스트 스텁을 만드는 것과 검증을 분리한다.
    • Mock 만드는 방법을 단일화했다.
    • API가 간단하다.
    • 실패 시에 발생하는 스택 트레이스가 깔끔하다.
  • 사용
    • CreateMock
      • 인터페이스에 해당되는 Mock 객체를 만든다.
    • Stub
      • 테스트에 필요한 Mock 객체의 동작을 지정한다.
    • Excercise
      • 테스트 메소드 내에서 Mock 객체를 사용한다.
    • Verify
      • 메서드가 예상되로 호출되었는지 검증한다.

Mock 사용 시 유의사항

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



Reference