맨위로가기

모의 객체

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

모의 객체는 소프트웨어 테스트에서 실제 객체를 대신하여 사용되는 객체로, 실제 객체와 동일한 인터페이스를 구현하여 클라이언트 객체가 모의 객체와 실제 객체를 구분하지 못하게 한다. 모의 객체를 사용하면 복잡한 객체의 동작을 모방하고, 테스트 중인 객체가 다양한 상태에 적절하게 응답하는지 확인할 수 있다. 모의 객체는 사용자 인터페이스 테스트, 데이터베이스 테스트 등에서 유용하게 사용되며, 테스트 주도 개발(TDD)에서 자동화된 테스트를 위해 활용된다. 하지만 모의 객체 사용은 테스트 코드의 구현 종속성을 높이고, 모의 객체의 정확한 모델링이 어려울 수 있다는 한계가 있다.

더 읽어볼만한 페이지

  • 유닛 테스트 - 메소드 스텁
    메소드 스텁은 소프트웨어 개발에서 상위 모듈 검사 시 미완성된 하위 모듈을 대신하는 가상 모듈로, 모듈 간 의존성 해결, 개발 속도 향상, 독립적인 테스트 환경 구축을 목적으로 사용된다.
  • 익스트림 프로그래밍 - 워드 커닝햄
    워드 커닝햄은 미국의 컴퓨터 프로그래머로, 최초의 위키 사이트 WikiWikiWeb을 만들고 기술 부채 개념을 창안했으며, 소프트웨어 개발 방법론 발전에 기여했다.
  • 익스트림 프로그래밍 - JUnit
    JUnit은 자바 환경에서 단위 테스트를 위한 프레임워크로, 반복적인 테스트 실행을 통해 버그 수정에 용이하며, 어노테이션 기반의 간편한 테스트 코드 작성과 IDE 통합을 지원하여 개발 효율성을 높인다.
  • 객체 지향 프로그래밍 - Is-a
    Is-a 관계는 객체 지향 프로그래밍에서 한 유형이 다른 유형의 하위 유형임을 나타내는 관계로, 상속, 서브타이핑, 리스코프 치환 원칙과 관련되며, C++, Python, Java 등에서 표현된다.
  • 객체 지향 프로그래밍 - 객체 (컴퓨터 과학)
    객체는 객체 지향 프로그래밍에서 데이터와 조작을 묶어 메시지를 수신하고, 프로그램의 개념을 표현하며 가시성과 재사용성을 높이는 실체이다.
모의 객체
일반 정보
Mockito 로고
Mockito 로고
유형소프트웨어 라이브러리
목적단위 테스트를 위한 모의 객체 생성
개발 언어자바
라이선스MIT 라이선스
상세 정보
설명단위 테스트에서 실제 객체 대신 사용되는 모의 객체를 생성하는 데 사용되는 프레임워크임.
특징가짜 객체 생성
객체 간의 상호 작용 검증
테스트 격리
장점테스트 속도 향상
의존성 제거
예외 처리 테스트 용이
단점과도한 모의 객체 사용 시 테스트 가독성 저하
실제 객체와의 차이로 인한 잠재적 오류 발생 가능성
사용 예시데이터베이스 연결 없이 데이터 접근 로직 테스트
외부 API 호출 없이 API 연동 로직 테스트
복잡한 객체 그래프에서 특정 객체의 동작만 테스트

2. 개념

모의 객체는 소프트웨어 테스터에게 자동차 디자이너가 차량 충돌 시 사람을 시뮬레이션하기 위해 충돌 시험용 마네킹을 사용하는 것과 같이 유용하다. 모의 객체는 모방하는 실제 객체와 동일한 인터페이스를 가지므로, 클라이언트 객체는 실제 객체를 사용하는지, 모의 객체를 사용하는지 알 수 없다.

많은 모의 객체 프레임워크를 사용하면 프로그래머는 모의 객체에서 어떤 메서드가 어떤 순서로 호출될지, 어떤 매개변수가 전달될지, 어떤 값이 반환될지를 지정할 수 있다. 따라서 네트워크 소켓과 같은 복잡한 객체의 동작을 모의 객체를 사용하여 모방할 수 있으며, 프로그래머는 테스트 중인 객체가 모의 객체가 가질 수 있는 다양한 상태에 적절하게 응답하는지 여부를 확인할 수 있다.

2. 1. 가짜 객체, 스텁과의 차이점

스텁, 페이크, 모의 객체의 정의는 문헌에 따라 일관되지 않는다.[1][2][3][4][5][6] 그럼에도 불구하고, 이들은 모두 동일한 인터페이스를 노출하여 테스트 환경에서 실제 객체를 나타낸다.

이름에 관계없이, 가장 단순한 형태는 미리 정해진 응답을 반환하고 (메서드 스텁에서처럼) 가장 복잡한 형태는 실제 객체의 완전한 로직을 모방한다.

이러한 테스트 객체는 각 호출의 컨텍스트를 검사하기 위한 어설션을 포함할 수 있다. 예를 들어, 모의 객체는 메서드가 호출되는 순서를 어설션하거나, 메서드 호출 간의 데이터 일관성을 어설션할 수 있다.

단위 테스트의 기술[7] 책에서 모의 객체는 객체와의 상호 작용이 발생했는지 여부를 검증하여 테스트가 실패했는지 또는 통과했는지 판단하는 데 도움이 되는 가짜 객체로 설명된다. 그 외의 모든 것은 스텁으로 정의된다. 해당 책에서 '페이크'는 실제가 아닌 모든 것으로, 사용법에 따라 '스텁' 또는 '모의 객체'가 될 수 있다.

3. 유용성

사용자 인터페이스(UI) 테스트나 데이터베이스 테스트와 같이 자동화된 테스트가 어렵거나 실제 객체를 사용하기 어려운 경우, 모의 객체가 유용하게 사용된다. 모의 객체는 실제 객체의 동작을 흉내 내어 테스트를 용이하게 한다.

모의 객체는 다음과 같은 특성을 가진 객체를 대신하여 사용될 때 유용하다.


  • 비결정적 결과(예: 현재 시간, 온도)를 제공하는 경우
  • 생성/재현이 어려운 상태(예: 네트워크 오류)를 가진 경우
  • 느린 경우 (예: 데이터베이스)
  • 아직 존재하지 않거나 동작이 변경될 수 있는 경우
  • 테스트를 위해 특정 정보나 메서드가 필요한 경우


예를 들어, 알람 시계 프로그램 테스트 시 실제 시간 서비스 대신 모의 시간 서비스를 사용하여 시간을 설정하고 테스트할 수 있다.

모의 객체는 실제 객체에 없는 추가적인 설정을 통해 예외를 발생시키거나, 응답 없이 멈추거나, null을 반환하는 등의 동작을 구현하여 백 엔드 오류에 대한 클라이언트 동작을 테스트할 수 있게 한다.

모의 데이터베이스 객체의 `save()` 메서드는 최소한의 구현만으로도 데이터 유효성 검사 등을 수행할 수 있다. 또한, 모의 메서드는 로그를 통해 수행된 작업의 수를 확인하여 성능 저하 버그를 발견하는 데 도움을 줄 수 있다.[8][9]

4. 테스트 주도 개발 (TDD)과의 관련성

테스트 주도 개발(TDD)에서는 자동화된 테스트가 필수적이다. 모의 객체를 이용하면 상당 부분의 테스트를 사용자의 개입 없이 자동화할 수 있다.[9]

테스트 주도 개발(TDD) 방식을 사용하는 프로그래머는 소프트웨어를 작성할 때 모의 객체를 사용한다. 모의 객체는 더 복잡한 실제 객체의 인터페이스 요구 사항을 충족하고 이를 대신한다. 따라서 프로그래머는 복잡한 기본 또는 협업 클래스를 호출하지 않고도 한 영역에서 기능을 작성하고 단위 테스트할 수 있다.[9] 개발자는 모의 객체를 사용하여 종속성에 대한 걱정 없이 테스트 대상 시스템의 동작에 집중할 수 있다. 예를 들어, 여러 객체가 특정 상태에 있는 것을 기반으로 하는 복잡한 알고리즘을 테스트하는 것은 실제 객체 대신 모의 객체를 사용하여 명확하게 표현할 수 있다.

복잡성 문제 외에도 관심사 분리를 통해 얻는 이점과 관련된 실제 속도 문제가 있다. TDD를 사용하여 실제 소프트웨어를 개발하는 것은 수백 개의 단위 테스트를 쉽게 포함할 수 있다. 이러한 테스트 중 다수가 데이터베이스, 웹 서비스 및 기타 프로세스 외부 또는 네트워크 시스템과의 통신을 유도하는 경우, 단위 테스트 모음은 정기적으로 실행하기에 너무 느려진다. 이는 결국 나쁜 습관으로 이어지고 개발자가 TDD의 기본 원칙을 유지하는 것을 꺼리게 만든다.

모의 객체가 실제 객체로 대체되면, 엔드 투 엔드 기능에 대한 추가 테스트가 필요하다. 이는 단위 테스트가 아닌 통합 테스트가 될 것이다.

5. 한계

모의 객체 사용은 단위 테스트를 테스트 대상 코드 구현에 밀접하게 연결시킬 수 있다. 예를 들어, 많은 모의 객체 프레임워크는 개발자가 테스트 대상인 실제 객체가 모의 객체 메서드를 호출한 순서와 횟수를 확인할 수 있게 해준다. 따라서 테스트 대상 코드의 후속 리팩토링은 모든 모의 객체 메서드가 이전 구현의 계약을 계속 준수하더라도 테스트가 실패하게 만들 수 있다. 이는 단위 테스트가 메서드의 내부 구현이 아닌 외부 동작을 테스트해야 함을 보여준다. 단위 테스트 모음의 일부로 모의 객체를 과도하게 사용하면 리팩토링이 진행됨에 따라 시스템 진화 과정에서 테스트 자체에 대해 수행해야 하는 유지 관리 양이 크게 증가할 수 있다. 이러한 테스트를 진화 과정에서 부적절하게 유지 관리하면 실제 클래스의 인스턴스를 사용하는 단위 테스트에서 발견될 수 있는 버그를 놓칠 수 있다. 반대로, 하나의 메서드만 모의하는 것은 전체 실제 클래스를 설정하는 것보다 훨씬 적은 구성을 필요로 할 수 있으므로 유지 관리 요구 사항을 줄일 수 있다.

모의 객체는 모의하는 객체의 동작을 정확하게 모델링해야 하며, 이는 모의 대상 객체가 다른 개발자나 프로젝트에서 가져오거나 아직 작성되지 않은 경우 달성하기 어려울 수 있다. 동작이 올바르게 모델링되지 않으면 단위 테스트가 통과로 기록될 수 있지만, 단위 테스트가 실행하는 동일한 조건에서 런타임에 실패가 발생하여 단위 테스트가 부정확해진다.[10]

참조

[1] 웹사이트 Unit testing best practices with .NET Core and .NET Standard - Let's speak the same language (Fake, Stubs and Mocks) https://docs.microso[...] 2022-09-03
[2] 웹사이트 Mocks and Stubs aren't Spies http://hamletdarcy.b[...] 2007-10-21
[3] 웹사이트 Mocks, Fakes, Stubs and Dummies http://xunitpatterns[...] 2024-01-17
[4] 웹사이트 What's the difference between a mock & stub? https://stackoverflo[...] 2022-07-04
[5] 웹사이트 What's the difference between faking, mocking, and stubbing? https://stackoverflo[...]
[6] 서적 Working effectively with legacy code Prentice Hall
[7] 서적 The art of unit testing Manning
[8] 문서 These examples use a nomenclature that is similar to that used in Unified Modeling Language
[9] 서적 Test-Driven Development By Example Addison Wesley
[10] 간행물 to Mocking | O'Reilly Media http://www.onjava.co[...] InJava.com



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com