2

공동 작업자 인 Foo에 대한 단위 테스트를 작성하고 있습니다 (Bar). Foo의 테스트에서 Bar의 수동 빌드 스텁 구현을 사용하고 싶습니다.init 메소드가 테스트 용 스텁 구현을 반환하도록하는 관용적 인 Objective-C 기법이 있습니까?

나는 자바에서이 일을한다면, 나는 FooBarFactory 협력자를주고 항상 내 StubBar을 반환 Foo의 시험에 MockBarFactory를 주입한다.

이 기술은 Objective-C에서 잘 작동하지만 동적 언어로 수행하는 데 특히 관용적 인 일은 아니라고 생각합니다. [[Bar alloc] init]StubBar을 반환 할 때 까다로운 작업을 수행 할 수 있는지 궁금합니다. 단원 테스트를 실행하고 있지만 실제 구현에서는 Bar의 정상 구현을 제공합니다.

또는이 경우 가장 적합한 것이 가장 명백한 공장 패턴입니까?

+0

단위 테스트를위한 코드가 "실생활"코드와 혼용되지 않을 것입니다. 어떻게 다르게 동작하는지 테스트가 잘되었는지 확신 할 수 있습니까? –

+0

@JonathanCichon 단위 테스트를 할 때 공통점이 있다고 생각합니까? 특정 객체 또는 함수 (이 경우 'Foo'와 같은)를 테스트하려는 경우에는 다른 이유로 완벽한 테스트 환경을 설정할 수있는 것은 아닙니다. 어쩌면'Foo'는 실제로 테스트와 관련이없는'Bar' 속성을 가져야합니다. – DrummerB

+0

아래에서 언급했듯이 단위 테스트에만 사용되는 경우 내 주요 타겟에 컴파일되는 내용을 추가하지 않는 것이 좋습니다. –

답변

1

init에서 다른 개체를 반환 할 수 있습니다. 그래서 [super init]의 반환 값을 self에 할당해야합니다. 다음과 같이 시도하십시오.

@implementation Bar 

- (id)init { 
    if (UNIT_TEST) { 
     self = [[StubBar alloc] init]; 
     if (self) { 
      // do unit test init here 
     } 
    } else { 
     self = [super init]; 
     if (self) { 
      // do regular init here 
     } 
    } 
    return self; 
} 

... 

@end 

참고 : 이것은 ARC에서 작동해야합니다. ARC를 사용하지 않는 경우 새 StubBar 인스턴스를 할당하기 전에 self을 출시해야합니다. 당신이 당신의 주요 목표로 단위 테스트 관련 코드를 컴파일하지 않도록하려면


:

@implementation Bar 

- (id)init { 
#if UNIT_TEST 
    self = [[StubBar alloc] init]; 
    if (self) { 
     // do unit test init here 
    } 
#else 
    self = [super init]; 
    if (self) { 
     // do regular init here 
    } 
#endif 
    return self; 
} 

... 

@end 

당신은 완전히 분리 된 단위 테스트와 실제 코드, 당신이 당신 Bar의 두 가지 버전을 가질 수 원하는 경우 수업. 하나는 실제 코드로 컴파일되고 다른 하나는 유닛 테스트 대상으로 컴파일됩니다.


당신은 쉽게 다음과 같이 컴파일시에 정확한 클래스 유형을 알지 못하고, 인스턴스를 할당 할 수 있습니다 :

id someBar = [[someClass alloc] init]; // assuming someClass is of type Class 

또는 :

id someBar = [[NSClassFromString(@"Bar") alloc] init]; 

첫 번째는하지만 바람직하다. 이것을 사용하여 단위 테스트를 수행 할 때 변경할 수있는 기본 클래스 유형을 가질 수 있습니다. Foo의 속성 또는 단위 테스트시 다시 정의하는 전처리 매크로.

+0

이것이 어떻게 작동하는지 알 수는 있지만, 실제 코드베이스에 단위 테스트 항목을 섞어 놓는 아이디어는 마음에 들지 않습니다. –

+0

@RobertAtkins 몇 가지 제안 사항이 추가되었습니다. 이 작업을 수행하는 데는 엄청난 방법이 있습니다. 나는 방법이 있다고 생각하지 않으며, 공장에서 언급 한 것처럼 제대로 작동 할 것입니다. – DrummerB

+0

필자의 경우, 'bar'가 테스트 대상 클래스에 의해 구현 된 경우 내 마지막 제안을 구현하는 방법을 이해하지 못합니다. Factory에서 Java로 해결할 수있는 문제는'new'는 정적 호출이며 런타임에 조롱 될 수 없다는 것입니다. 내 질문의 요지는 "[Bar 할당]이 정적 호출이라는 사실을 해결하기 위해 Objective-C에서 할 수있는 뭔가가 있습니까?" –

0

당신이 찾고있는 것은 OCMock의 라인을 따라 무엇인가입니다. 클래스, 프로토콜 및 특히 단위 테스트 용으로 만들어진 모의 객체를 작성할 수 있습니다.

관련 문제