이 용어를 어떻게 사용하는지 알고 있지만 단위 테스트를 위해 가짜 , 조롱 및 스터 빙에 대한 정의가 허용되는지 궁금합니다 . 테스트를 위해 이것을 어떻게 정의합니까? 각각을 사용할 수있는 상황을 설명하십시오.
사용 방법은 다음과 같습니다.
Fake : 인터페이스를 구현하지만 고정 데이터를 포함하고 로직은없는 클래스입니다. 구현에 따라 단순히 “양호한”또는 “나쁜”데이터를 반환합니다.
Mock : 인터페이스를 구현하고 특정 메소드에서 발생하도록 리턴 / 예외로 값을 동적으로 설정하고 특정 메소드가 호출되었는지 여부를 확인할 수있는 기능을 제공하는 클래스입니다.
스텁 : 메소드가 호출되었는지 여부를 확인할 수있는 기능을 제공하지 않는다는 점을 제외하고 모의 클래스와 같습니다.
목과 스터브는 손으로 만들거나 조롱 프레임 워크로 생성 할 수 있습니다. 가짜 클래스는 손으로 생성됩니다. 나는 주로 클래스를 사용하여 클래스와 종속 클래스 간의 상호 작용을 확인합니다. 상호 작용을 확인하고 코드를 통해 대체 경로를 테스트하면 스텁을 사용합니다. 필자는 가짜 클래스를 사용하여 데이터 종속성을 추출하거나 매번 설정하기가 너무 지루한 경우가 있습니다.
답변
당신은 몇 가지 정보를 얻을 수 있습니다 :
에서 모의와 스텁에 대한 마틴 파울러
가짜 객체는 실제로 작동하는 구현이 있지만 일반적으로 생산에 적합하지 않은 몇 가지 단축키를 사용합니다.
스텁 은 일반적으로 테스트를 위해 프로그래밍 된 외부의 항목에는 전혀 응답하지 않는 테스트 중에 작성된 호출에 대해 미리 준비된 답변을 제공합니다. 스텁은 ‘보낸’메시지를 기억하는 전자 메일 게이트웨이 스텁 또는 ‘보낸’메시지 수와 같은 통화에 대한 정보를 기록 할 수도 있습니다.
Mocks 는 우리가 여기서 말하는 것입니다. 기대되는 사전 프로그래밍 된 객체는 그들이받을 전화의 사양을 형성합니다.
에서 xunitpattern :
가짜 : SUT가 의존하는 구성 요소에서 제공하는 것과 동일한 기능을 매우 가볍게 구현하거나 구현하여 SUT가 실제 대신 SUT에 사용하도록 지시합니다.
Stub :이 구현은 SUT 내에서 테스트되지 않은 코드 (X 페이지의 생산 버그 참조)를 행사할 값 (또는 예외)으로 SUT의 호출에 응답하도록 구성됩니다. 테스트 스텁 사용에 대한 주요 표시는 SUT의 간접 입력을 제어 할 수 없기 때문에 테스트되지 않은 코드가 있다는 것입니다.
테스트 대상 시스템 (SUT)이 의존하는 객체와 동일한 인터페이스를 구현하는 모의 객체 . SUT에서 호출 메소드의 부작용을 관찰 할 수 없기 때문에 테스트되지 않은 요구 사항 (X 페이지의 생산 버그 참조)이 발생하지 않도록 동작 검증을 수행해야하는 경우 모의 객체를 관찰 지점으로 사용할 수 있습니다.
몸소
Mock and Stub을 사용하여 단순화하려고합니다. 테스트 된 클래스로 설정된 값을 반환하는 객체 인 경우 Mock을 사용합니다. Stub을 사용하여 테스트 할 인터페이스 또는 추상 클래스를 모방합니다. 실제로, 실제로 무엇을 부르든 상관 없습니다. 프로덕션에서 사용되지 않는 모든 클래스이며 테스트를위한 유틸리티 클래스로 사용됩니다.
답변
스텁 -메소드 호출에 사전 정의 된 응답을 제공하는 오브젝트입니다.
모의 -기대치를 설정하는 대상.
가짜 -가짜 웹 서비스와 같이 제한된 기능 (테스트 목적으로)을 가진 객체.
Test Double은 스텁, 모의 및 가짜에 대한 일반적인 용어입니다. 그러나 비공식적으로 사람들은 종종 사람들을 모의라고 부르는 것을들을 수 있습니다.
답변
이 질문이 오랫동안 지속되어 왔으며 아무도 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
.
나는 가짜에 대한 주장을 쓰는 것이 일반적인 관행이라는 것을 알고 있습니다. 나는 고전주의 캠프 ( Martin Fowler의 “Mocks aren ‘s Stubs” 참조)에서 Martin Fowler 와 확고하고 Osherove처럼 상호 작용 테스트 (가짜에 대한 주장으로 만 수행 할 수 있음)를 최대한 피하십시오.
여기에 정의 된 모의를 피해야하는 이유에 대한 재미있는 내용을 보려면 “Fowler mockist classicist”를 검색하십시오. 당신은 많은 의견을 찾을 수 있습니다.
답변
최상위 투표 답변에서 언급했듯이 Martin Fowler는 Mocks Are n’t Stubs의 이러한 차이점 , 특히 Mocks와 Stubs의 차이점 소제목에 대해 설명 하므로 해당 기사를 읽으십시오.
이런 것들이 어떻게 다른지에 초점을 맞추기보다는 그것들이 왜 독특한 개념 인지 에 초점을 맞추는 것이 더 밝다고 생각합니다 . 각각 다른 목적으로 존재합니다.
가짜
가짜는 그 동작합니다 “자연”을 구현 한 것입니다 만, “진짜”아니다. 이것들은 희미한 개념이므로 다른 사람들은 사물을 가짜로 만드는 것에 대한 다른 이해를 가지고 있습니다.
가짜의 한 예는 메모리 내 데이터베이스입니다 (예 : :memory:
상점 과 함께 sqlite 사용 ). 데이터가 지속되지 않기 때문에 프로덕션에는이 기능을 사용하지 않지만 테스트 환경에서 사용하기에는 데이터베이스로 적합합니다. 또한 “실제”데이터베이스보다 훨씬 가볍습니다.
다른 예로, 프로덕션 환경에서는 일종의 객체 저장소 (예 : Amazon S3)를 사용하지만 테스트에서는 디스크의 파일에 객체를 간단히 저장할 수 있습니다. “디스크에 저장”구현은 가짜 일 것입니다. 또는 메모리 내 파일 시스템을 대신 사용하여 “디스크에 저장”작업을 가짜로 만들 수도 있습니다.
세 번째 예로 캐시 API를 제공하는 객체를 상상해보십시오. 올바른 인터페이스를 구현하지만 캐싱을 전혀 수행하지 않지만 항상 캐시 미스를 반환하는 객체는 일종의 가짜입니다.
가짜의 목적은 하지 테스트중인 시스템의 동작에 영향을 미치는 것이 아니라 할 구현 단순화 (불필요하거나 헤비급 종속성을 제거하여) 시험을.
스텁
스터브는 “비정상적”동작을 구현 한 것이다. 특정 출력으로 특정 입력에 응답하도록 미리 설정되어 있습니다 (보통 테스트 설정에 의해).
스텁의 목적은 테스트중인 시스템을 특정 상태로 만드는 것입니다. 예를 들어 REST API와 상호 작용하는 일부 코드에 대한 테스트를 작성하는 경우 항상 미리 준비된 응답을 리턴하거나 특정 오류로 API 요청에 응답하는 API로 REST API를 스텁 아웃 할 수 있습니다. 이렇게하면 시스템이 이러한 상태에 어떻게 반응하는지에 대한 주장을하는 테스트를 작성할 수 있습니다. 예를 들어, API가 404 오류를 반환하면 사용자가받는 응답을 테스트합니다.
스텁은 일반적으로 응답하도록 지시 한 정확한 상호 작용에만 응답하도록 구현됩니다. 그러나 스텁을 만드는 주요 기능은 그 목적입니다 . 스텁은 테스트 케이스 설정에 관한 것입니다.
목신
모의는 그루터기에, 그러나와 유사하다 검증 에 추가했다. 모의의 목적은 테스트중인 시스템이 종속성과 상호 작용하는 방법에 대한 주장을하는 것입니다 .
예를 들어 파일을 웹 사이트에 업로드하는 시스템에 대한 테스트를 작성하는 경우 파일을 허용하고 업로드 된 파일이 올바른지 확인하는 데 사용할 수 있는 모의 객체 를 작성할 수 있습니다. 또는 더 작은 규모로, 테스트 대상 시스템이 모의 오브젝트의 특정 메소드를 호출하는지 확인하기 위해 모의 오브젝트를 사용하는 것이 일반적입니다.
Mocks는 특정 테스트 방법론 인 상호 작용 테스트에 연결되어 있습니다. 시스템 상호 작용 보다는 시스템 상태 를 테스트하려는 사람들은 모의를 거의 사용하지 않을 것입니다.
테스트 복식
가짜, 스터브 및 모의는 모두 테스트 복식 카테고리에 속합니다 . 테스트 이중은 다른 것 대신 테스트에서 사용하는 모든 객체 또는 시스템 입니다. 대부분의 자동화 된 소프트웨어 테스트에는 어떤 종류의 테스트 복식을 사용하는 것이 포함됩니다. 다른 종류의 테스트 더블에는 더미 값 , 스파이 및 I / O 블랙홀이 포함 됩니다.
답변
스텁과 모의 사용법을 설명하기 위해 Roy Osherove의 ” The Art of Unit Testing “을 기반으로 한 예제도 포함하고 싶습니다 .
로그를 인쇄하는 유일한 기능을 가진 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);
}
}
답변
당신이 주장하는 것은 모의 객체 라고 불리우며 테스트 실행에 도움이 된 다른 모든 것은 스텁 입니다.
답변
테스트를 표현하는 것이 중요합니다. 테스트에서 두 개체 간의 관계를 설명하려면 Mock에 대한 기대치를 설정했습니다. 테스트에서 흥미로운 동작을하도록 지원 객체를 설정하는 경우 반환 값을 스텁합니다.