2011-09-14 14 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進行了隱式調用。我編輯了我的帖子,以更好地反映這一點。 –