문제

나는 이 용어를 어떻게 사용하는지 알고 있지만 다음에 대한 정의가 허용되는지 궁금합니다. 가짜, 조롱, 그리고 스터빙 단위 테스트를 위해?테스트를 위해 이를 어떻게 정의합니까?각각을 사용할 수 있는 상황을 설명하세요.

내가 사용하는 방법은 다음과 같습니다.

가짜:인터페이스를 구현하지만 고정 데이터를 포함하고 논리는 포함하지 않는 클래스입니다.구현에 따라 단순히 "좋은" 또는 "나쁜" 데이터를 반환합니다.

모조품:인터페이스를 구현하고 특정 메서드에서 발생하는 반환/예외 값을 동적으로 설정하는 기능을 허용하고 특정 메서드가 호출되었는지/호출되지 않았는지 확인하는 기능을 제공하는 클래스입니다.

그루터기:메서드가 호출되었는지/호출되지 않았는지 확인하는 기능을 제공하지 않는다는 점을 제외하면 모의 클래스와 같습니다.

모의 및 스텁은 수동으로 생성하거나 모의 프레임워크를 통해 생성할 수 있습니다.가짜 클래스는 손으로 생성됩니다.나는 주로 내 클래스와 종속 클래스 간의 상호 작용을 확인하기 위해 모의 객체를 사용합니다.상호 작용을 확인한 후 코드를 통해 대체 경로를 테스트하고 나면 스텁을 사용합니다.나는 주로 데이터 종속성을 추상화하거나 모의/스텁이 매번 설정하기에는 너무 지루할 때 가짜 클래스를 사용합니다.

도움이 되었습니까?

해결책

정보를 얻을 수 있습니다.

에서 모의와 스텁에 대한 마틴 파울러

가짜 객체에는 실제로 작업 구현이 있지만 일반적으로 일부 바로 가기를 사용하여 생산에 적합하지 않습니다.

스터브 테스트 중에 이루어진 통화에 대한 통조림 답변을 제공하며, 일반적으로 테스트를 위해 프로그래밍 된 내용 외부에 전혀 응답하지 않습니다. Stubs는 또한 '보내기'메시지를 기억하는 전자 메일 게이트웨이 스터브와 같은 통화에 대한 정보를 기록하거나 '전송 된 메시지 수를 몇 개만 보낼 수 있습니다.

조롱 우리가 여기서 이야기하고있는 것입니다 : 그들이받을 것으로 예상되는 통화의 사양을 형성하는 기대치로 사전 프로그래밍 된 물체.

에서 xunitpattern:

가짜: 우리는 SUT가 실수 대신 SUT에 의존하고 SUT에 사용하도록 지시하는 구성 요소에 의해 제공되는 것과 동일한 기능을 매우 가벼운 구현을 획득하거나 구축합니다.

그루터기 :이 구현은 SUT 내에서 테스트되지 않은 코드 (X 페이지의 프로덕션 버그 참조)를 수행 할 값 (또는 예외)이있는 SUT의 통화에 응답하도록 구성됩니다. 테스트 스텁을 사용하는 주요 표시는 SUT의 간접 입력을 제어 할 수 없어 테스트되지 않은 코드가 있습니다.

모의 개체 이는 SUT (테스트중인 시스템)가 의존하는 객체와 동일한 인터페이스를 구현합니다. SUT에서 호출 방법의 부작용을 관찰 할 수 없기 때문에 테스트되지 않은 요구 사항 (X의 생산 버그 참조)을 피하기 위해 행동 검증을 수행해야 할 때 모의 개체를 관찰 지점으로 사용할 수 있습니다.

몸소

Mock and Stub을 사용하여 단순화하려고합니다. 나는 그것이 테스트 된 클래스로 설정된 값을 반환하는 객체 일 때 Mock을 사용합니다. 스터브를 사용하여 테스트 할 인터페이스 또는 추상 클래스를 모방합니다. 실제로, 당신이 무엇을 부르는지는 중요하지 않으며, 생산에 사용되지 않는 모든 클래스이며 테스트를위한 유틸리티 클래스로 사용됩니다.

다른 팁

그루터기 - 메소드 호출에 미리 정의 된 답변을 제공하는 객체.

모조품 - 기대치를 설정하는 대상.

가짜 - 기능이 제한된 객체 (테스트 목적으로) (예 : 가짜 웹 서비스).

테스트 더블은 스터브, 모의 및 가짜의 일반적인 용어입니다. 그러나 비공식적으로, 사람들은 종종 사람들이 단순히 그들을 모의라고 부르는 것을들을 수 있습니다.

이 질문이 오랫동안 주변에 있었고 아무도 아직 답을 제공하지 않은 것에 놀랐습니다. Roy Osherove의 "단위 테스트의 기술".

"3.1 스터브 소개"에서 스텁을 다음과 같이 정의합니다.

스텁은 시스템의 기존 의존성 (또는 협업자)을 제어 할 수있는 대체물입니다. 스텁을 사용하면 종속성을 직접 처리하지 않고도 코드를 테스트 할 수 있습니다.

스텁과 모의의 차이를 다음과 같이 정의합니다.

모의 대 스텁에 대해 기억해야 할 가장 중요한 것은 모의가 스터브와 같지만 모의 물체에 대해 주장하지만 스터브에 대해 주장하지는 않습니다.

가짜는 스터브와 모의 모두에 사용되는 이름입니다. 예를 들어 스텁과 모의의 구별에 신경 쓰지 않을 때.

Osherove의 스터브와 모의를 구별하는 방식은 테스트를 위해 가짜로 사용되는 클래스가 스터브 또는 모의 일 수 있음을 의미합니다. 특정 테스트의 경우는 전적으로 테스트에서 검사를 작성하는 방법에 따라 다릅니다.

  • 테스트가 테스트중인 클래스의 값을 확인하거나 실제로 가짜 이외의 곳에서 값을 확인할 때 가짜는 스터브로 사용되었습니다. 그것은 단지 테스트중인 클래스에 대한 값을 사용하여 사용하기 위해 사용하기 위해 또는 호출에 대한 호출에 의해 반환 된 값을 직접 또는 호출의 결과로 부작용 (일부 상태)을 유발하여 간접적으로 사용했습니다.
  • 테스트에서 가짜의 값을 확인하면 모의로 사용되었습니다.

클래스 fakex가 스터브로 사용되는 테스트의 예 :

const pleaseReturn5 = 5;
var fake = new FakeX(pleaseReturn5);
var cut = new ClassUnderTest(fake);

cut.SquareIt;

Assert.AreEqual(25, cut.SomeProperty);

그만큼 fake 인스턴스는 스터브로 사용됩니다 Assert 사용하지 않습니다 fake 조금도.

테스트 클래스 X가 모의로 사용되는 테스트의 예 :

const pleaseReturn5 = 5;
var fake = new FakeX(pleaseReturn5);
var cut = new ClassUnderTest(fake);

cut.SquareIt;

Assert.AreEqual(25, fake.SomeProperty);

이 경우 Assert 값을 확인합니다 fake, 그 가짜 조롱을 만들었습니다.

물론,이 사례들은 고도로 고안되었지만, 나는이 차이점에서 큰 장점을 봅니다. 그것은 당신이 당신의 물건을 어떻게 테스트하고 있는지, 테스트의 종속성이 어디에 있는지 알 수있게합니다.

나는 Osherove의 것과 동의합니다

순수한 유지 관리 가능성 관점에서, 모의를 사용하는 내 테스트에서는 사용하지 않는 것보다 더 많은 어려움이 생깁니다. 그것은 내 경험 이었지만 항상 새로운 것을 배우고 있습니다.

가짜에 대해 주장하는 것은 테스트가 전혀 테스트 중이 아닌 클래스의 구현에 테스트가 크게 의존하기 때문에 실제로 피하고 싶은 것입니다. 이는 수업 테스트를 의미합니다 ActualClassUnderTest 구현이기 때문에 깨지기 시작할 수 있습니다 ClassUsedAsMock 변경. 그리고 그것은 나에게 파울 냄새를 보냅니다. 테스트 ActualClassUnderTest 바람직하게는 때만 끊어 야합니다 ActualClassUnderTest 변경되었습니다.

나는 가짜에 대한 글쓰기가 특히 TDD 가입자의 모킹 유형 일 때 일반적인 관행이라는 것을 알고 있습니다. 나는 클래식리스트 캠프에서 Martin Fowler와 굳건히 있다고 생각합니다 ( Martin Fowler의 "Mocks Not Stubs") 그리고 Osherove와 마찬가지로 상호 작용 테스트를 피하십시오 (가짜에 대해서만 주장 할 수 있음).

여기에 정의 된 모의를 피해야하는 이유를 재미있게 읽으려면 "Fowler Mockist Classicist"에 대한 Google. 당신은 많은 의견을 찾을 수 있습니다.

가장 큰 대답에 의해 언급 된 바와 같이, Martin Fowler는 이러한 차이점에 대해 논의합니다. 모의는 스터브가 아닙니다, 특히 소제목 모의와 스터브의 차이, 해당 기사를 읽으십시오.

집중하기보다는 어떻게 이런 것들이 다릅니다. 집중하는 것이 더 깨달았다 고 생각합니다. 이것들은 뚜렷한 개념입니다. 각각은 다른 목적으로 존재합니다.

가짜

가짜 "자연스럽게"행동하지만 "실제"가 아닌 구현입니다. 이것들은 퍼지 개념이므로 다른 사람들은 사물을 가짜로 만드는 것에 대한 이해가 다릅니다.

가짜의 한 예는 메모리 인 데이터베이스입니다 (예 : sqlite를 사용하여 :memory: 가게). 데이터가 지속되지 않으므로 프로덕션에 사용하지는 않지만 테스트 환경에서 사용하기에 데이터베이스로 완벽하게 적합합니다. 또한 "실제"데이터베이스보다 훨씬 가볍습니다.

또 다른 예로서, 생산에서 일종의 객체 저장소 (예 : Amazon S3)를 사용하지만 테스트에서는 단순히 디스크 파일에 객체를 저장할 수 있습니다. 그러면 "디스크에 저장"구현은 가짜입니다. (또는 대신 메모리 파일 시스템을 사용하여 "디스크에 저장"작업을 위조 할 수도 있습니다.)

세 번째 예로, 캐시 API를 제공하는 객체를 상상해보십시오. 올바른 인터페이스를 구현하지만 단순히 캐싱을 전혀 수행하지 않지만 항상 캐시 미스를 반환하는 객체는 일종의 가짜입니다.

가짜의 목적은입니다 ~ 아니다 테스트중인 시스템의 동작에 영향을 미칩니다, 오히려 구현을 단순화하십시오 테스트의 (불필요한 또는 헤비급 종속성을 제거함으로써).

스터브

그루터기 "자연스럽게"행동하는 구현입니다. 특정 출력이있는 특정 입력에 응답하는 것은 사전 구성 (일반적으로 테스트 설정에 의해)입니다.

스텁의 목적은 시스템을 특정 상태로 테스트하는 것입니다. 예를 들어, REST API와 상호 작용하는 일부 코드에 대한 테스트를 작성하는 경우 스터브 아웃 API가있는 나머지 API는 항상 통조림 응답을 반환하거나 특정 오류가있는 API 요청에 응답합니다. 이렇게하면 시스템이 이러한 상태에 어떻게 반응하는지에 대한 주장을하는 테스트를 작성할 수 있습니다. 예를 들어, API가 404 오류를 반환하는 경우 사용자가 얻는 응답 테스트.

스텁은 일반적으로 응답하라고 말한 정확한 상호 작용에만 응답하기 위해 구현됩니다. 그러나 무언가를 스터브로 만드는 주요 기능은 목적: 스텁은 테스트 케이스 설정에 관한 것입니다.

조롱

모조품 스텁과 비슷하지만 확인 추가. 모의의 목적은 테스트중인 시스템이 종속성과 어떻게 상호 작용하는지에 대한 주장을하는 것입니다..

예를 들어, 파일을 웹 사이트에 업로드하는 시스템에 대한 테스트를 작성하는 경우 모조품 파일을 수락하고 업로드 된 파일이 올바른 것으로 주장하는 데 사용할 수 있습니다. 또는 더 작은 규모로 테스트하에있는 시스템이 조롱 된 물체의 특정 방법을 호출하는지 확인하기 위해 객체의 모의를 사용하는 것이 일반적입니다.

모의가 묶여 있습니다 상호 작용 테스트, 특정 테스트 방법론입니다. 테스트를 선호하는 사람들 시스템 상태 보다는 시스템 상호 작용 모의가 거의 없으면 조롱을 사용합니다.

테스트 복식

가짜, 스터브 및 모의는 모두 범주에 속합니다. 테스트 복식. 테스트 더블은 테스트에서 사용하는 모든 객체 또는 시스템입니다. 대신에 다른 것. 대부분의 자동화 된 소프트웨어 테스트에는 어떤 종류의 테스트 복식 사용이 포함됩니다. 다른 종류의 테스트 복식에는 다음이 포함됩니다 더미 값, 스파이, 및 I/O 블랙홀.

스텁과 모의의 사용법을 설명하기 위해 Roy Osherove의 "단위 테스트의 기술".

로그를 인쇄하는 유일한 기능을 가진 LogAnalyzer 애플리케이션이 있다고 상상해 보십시오.웹 서비스와 통신해야 할 뿐만 아니라 웹 서비스에서 오류가 발생하면 LogAnalyzer는 다른 외부 종속성에 오류를 기록하고 이를 웹 서비스 관리자에게 이메일로 보내야 합니다.

LogAnalyzer 내에서 테스트하려는 논리는 다음과 같습니다.

if(fileName.Length<8)
{
 try
  {
    service.LogError("Filename too short:" + fileName);
  }
 catch (Exception e)
  {
    email.SendEmail("a","subject",e.Message);
  }
}

웹 서비스에서 예외가 발생할 때 LogAnalyzer가 이메일 서비스를 올바르게 호출하는지 어떻게 테스트합니까?우리가 직면한 질문은 다음과 같습니다.

  • 웹 서비스를 어떻게 대체할 수 있나요?

  • 웹 서비스에서 예외를 어떻게 시뮬레이션하여 이메일 서비스로 통화를 테스트 할 수 있습니까?

  • 이메일 서비스가 올바르게 또는 전혀 호출되었음을 어떻게 알 수 있습니까?

우리는 처음 두 가지 질문을 다음과 같이 처리할 수 있습니다. 웹 서비스에 스텁 사용.세 번째 문제를 해결하기 위해 우리는 이메일 서비스에 모의 객체를 사용하세요.

가짜는 스텁이나 모의를 설명하는 데 사용할 수 있는 일반적인 용어입니다. 테스트에서는 두 개의 가짜가 있습니다.하나는 이메일 서비스 모형으로, 올바른 매개변수가 이메일 서비스로 전송되었는지 확인하는 데 사용할 것입니다.다른 하나는 웹 서비스에서 발생한 예외를 시뮬레이션하는 데 사용할 스텁입니다.테스트 결과를 확인하기 위해 웹 서비스 가짜를 사용하지 않고 테스트가 올바르게 실행되는지 확인하기 때문에 이는 스텁입니다.이메일 서비스는 그것이 올바르게 호출되었다고 우리가 주장할 것이기 때문에 모의 서비스입니다.

[TestFixture]
public class LogAnalyzer2Tests
{
[Test]
 public void Analyze_WebServiceThrows_SendsEmail()
 {
   StubService stubService = new StubService();
   stubService.ToThrow= new Exception("fake exception");
   MockEmailService mockEmail = new MockEmailService();

   LogAnalyzer2 log = new LogAnalyzer2();
   log.Service = stubService
   log.Email=mockEmail;
   string tooShortFileName="abc.ext";
   log.Analyze(tooShortFileName);

   Assert.AreEqual("a",mockEmail.To); //MOCKING USED
   Assert.AreEqual("fake exception",mockEmail.Body); //MOCKING USED
   Assert.AreEqual("subject",mockEmail.Subject);
 }
}

테스트를 표현하는 문제입니다. 테스트가 두 개체 간의 관계를 설명하기 위해 테스트를 원한다면 모의에 대한 기대치를 설정했습니다. 나는 테스트에서 흥미로운 행동을 취하기 위해 지원 객체를 설정하는 경우 값을 스텁 리턴 값입니다.

당신이 그것에 대해 주장하는 것은 모조품 객체와 테스트 실행에 도움이되는 모든 것은 그루터기.

당신이 배열-액트-어스 트에 익숙하다면, 당신에게 유용한 스터브와 모의의 차이를 설명하는 한 가지 방법은 스터브가 입력 상태를 배열하기 위해 배열 섹션에 속하고 모의가 속한다는 것입니다. 결과를 주장하기 위해서는 어설 싱 섹션입니다.

인형은 아무것도하지 않습니다. 매개 변수 목록을 채우기위한 것이므로 정의되지 않거나 널 오류가 발생하지 않습니다. 또한 엄격하게 입력 한 언어로 유형 검사기를 만족시키기 위해 존재하므로 컴파일하고 실행할 수 있습니다.

그루터기 그리고 가짜 입력 매개 변수에 따라 응답을 변경할 수 있다는 객체입니다. 그들 사이의 주요 차이점은 가짜가 스터브보다 실제 구현에 더 가깝다는 것입니다. 스텁에는 기본적으로 예상 요청에 대한 하드 코딩 된 응답이 포함되어 있습니다. 예를 들어보십시오 :

public class MyUnitTest {

 @Test
 public void testConcatenate() {
  StubDependency stubDependency = new StubDependency();
  int result = stubDependency.toNumber("one", "two");
  assertEquals("onetwo", result);
 }
}

public class StubDependency() {
 public int toNumber(string param) {
  if (param == “one”) {
   return 1;
  }
  if (param == “two”) {
   return 2;
  }
 }
}

모조품 가짜와 스터브에서 한 걸음 더 올라갑니다. 모형은 스텁과 동일한 기능을 제공하지만 더 복잡합니다. API의 순서 방법을 지시하는 규칙을 정의 할 수 있습니다. 대부분의 모의는 방법이 몇 번이나 호출되었는지 추적 할 수 있으며 해당 정보에 따라 반응 할 수 있습니다. 모의는 일반적으로 각 통화의 맥락을 알고 있으며 다른 상황에서 다르게 반응 할 수 있습니다. 이로 인해 조롱은 조롱하는 수업에 대한 지식이 필요합니다. 스텁은 일반적으로 방법이 몇 번이나 호출되었는지 또는 일련의 방법이 호출되었는지 추적 할 수 없습니다. 모의는 다음과 같습니다.

public class MockADependency {

 private int ShouldCallTwice;
 private boolean ShouldCallAtEnd;
 private boolean ShouldCallFirst;

 public int StringToInteger(String s) {
  if (s == "abc") {
   return 1;
  }
  if (s == "xyz") {
   return 2;
  }
  return 0;
 }

 public void ShouldCallFirst() {
  if ((ShouldCallTwice > 0) || ShouldCallAtEnd)
   throw new AssertionException("ShouldCallFirst not first thod called");
  ShouldCallFirst = true;
 }

 public int ShouldCallTwice(string s) {
  if (!ShouldCallFirst)
   throw new AssertionException("ShouldCallTwice called before ShouldCallFirst");
  if (ShouldCallAtEnd)
   throw new AssertionException("ShouldCallTwice called after ShouldCallAtEnd");
  if (ShouldCallTwice >= 2)
   throw new AssertionException("ShouldCallTwice called more than twice");
  ShouldCallTwice++;
  return StringToInteger(s);
 }

 public void ShouldCallAtEnd() {
  if (!ShouldCallFirst)
   throw new AssertionException("ShouldCallAtEnd called before ShouldCallFirst");
  if (ShouldCallTwice != 2) throw new AssertionException("ShouldCallTwice not called twice");
  ShouldCallAtEnd = true;
 }

}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top