2011-09-14 2 views
4

init 메소드에서 사용 된 메소드를 스텁합니까? 내 수업에서OCMock으로 스텁 된 값으로 객체를 초기화하는 방법

관련 방법 :

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     if (self.adConfigurationType == AdConfigurationTypeDouble) { 
      [self configureForDoubleConfiguration]; 
     } 
     else { 
      [self configureForSingleConfiguration]; 
     } 
    } 
    return self; 
} 

- (AdConfigurationType)adConfigurationType 
{ 
    if (adConfigurationType == NSNotFound) { 
     if ((random()%2)==1) { 
      adConfigurationType = AdConfigurationTypeSingle; 
     } 
     else { 
      adConfigurationType = AdConfigurationTypeDouble; 
     } 
    } 
    return adConfigurationType; 
} 

내 시험 :

- (void)testDoubleConfigurationLayout 
{ 
    id mockController = [OCMockObject mockForClass:[AdViewController class]]; 
    AdConfigurationType type = AdConfigurationTypeDouble; 
    [[[mockController stub] andReturnValue:OCMOCK_VALUE(type)] adConfigurationType]; 

    id controller = [mockController init]; 

    STAssertNotNil([controller smallAdRight], @"Expected a value here"); 
    STAssertNotNil([controller smallAdRight], @"Expected a value here"); 
    STAssertNil([controller largeAd], @"Expected nil here"); 
} 

내 결과 : 인해 캐치되지 않는 예외 'NSInternalInconsistencyException'응용 프로그램 종료, 이유는

: 'OCMockObject [ AdViewController] : 예상치 못한 메소드 호출 : smallAdRight '

그렇다면 OCMockObject에서 AdViewController에 어떻게 액세스 할 수 있습니까?

답변

12

mockForClass: 메서드를 사용하는 경우 조롱 된 클래스에서 호출되는 모든 메서드마다 스텁 된 구현을 제공해야합니다. 첫 번째 테스트에서 [controller smallAdRight]로 전화를 걸면됩니다.

대신에 조롱되지 않은 메시지를 무시하는 niceMockForClass: 방법을 사용할 수 있습니다.

또 다른 방법은 AdViewController을 인스턴스화 한 다음 partialMockForObject: 메서드를 사용하여 부분 모의 작업을 만드는 것입니다. 이렇게하면 컨트롤러 클래스의 내부가 작업의 주요 부분을 수행하게됩니다.

다만 ... AdViewController 또는이 클래스를 사용하는 클래스를 테스트하려고합니까? 전체 클래스를 조롱하고 여전히 정상적으로 작동하는지 테스트하는 것으로 보입니다. 특정 값이 주입 할 때 예상대로 AdViewController 동작합니다을 테스트하려는 경우, 당신의 최선의 선택은 가능성이 가장 높은 partialMockForObject: 방법 : 클로스 '대답에 두 개의 작은 편집 제작

- (void)testDoubleConfigurationLayout {  
    AdViewController *controller = [AdViewController alloc]; 
    id mock = [OCMockObject partialMockForObject:controller]; 
    AdConfigurationType type = AdConfigurationTypeDouble; 
    [[[mock stub] andReturnValue:OCMOCK_VALUE(type)] adConfigurationType]; 

    // You'll want to call init after the object have been stubbed 
    [controller init] 

    STAssertNotNil([controller smallAdRight], @"Expected a value here"); 
    STAssertNotNil([controller smallAdRight], @"Expected a value here"); 
    STAssertNil([controller largeAd], @"Expected nil here"); 
} 
+0

하지만, 본질적으로 제안 된 테스트 구현은 이제 통과해야 – nduplessis

+0

때때로 init 메소드가 일회성 구성을 수행하기 때문에 테스트하려는 경로가이 접근 방식으로 실행되지 않습니다. 이러한 유형의 테스트는 일반적으로 첫 번째 행에서 [AdViewController alloc]을 호출하면 작동합니다. –

+0

포스트를 다시 한번 읽으면 컨트롤러가 조롱을 당할 때까지 init을 호출해서는 안된다는 것이 나에게 분명합니다. 처음으로 속성을 통해 실제로 adConfigurationType에 대한 암시 적 호출을 한 것을 눈치 채지 못했습니다. 이 글을 잘 반영하기 위해 내 글을 수정했습니다. –