2013-12-09 59 views
5

剛開始xcode 5和xctest。如何測試按鈕按下時加載視圖。我已經加入編程方法rightBarButtonItem點擊xctest - 如何測試一個新的視圖加載按鈕按

action:@selector(onSettingsButton) 

和onSettingsButton

-(void) onSettingsButton{ 
    SettingsViewController *svc = [[SettingsViewController alloc] init]; 
    [self.navigationController pushViewController:svc animated:YES]; 
} 

時調用如何編寫xctest確保SettingsViewController可以調出設置有何看法?謝謝。

回答

4

您需要一個交互測試 - 即檢查對象之間交互的測試。在這種情況下,您需要測試在導航控制器上調用-pushViewController:animated:SettingsViewController。所以我們想把一個模擬對象放入self.navigationController,我們可以問:「你按預期打電話了嗎?」

我將假設該類的一個簡單名稱:MyView。

我會這樣做的方式是子類和覆蓋navigationController。所以在我的測試代碼,我會做這樣的事情:

@interface TestableMyView : MyView 
@property (nonatomic, strong) id mockNavigationController; 
@end 

@implementation TestableMyView 

- (UINavigationController *)navigationController 
{ 
    return mockNavigationController; 
} 

@end 

現在,而不是創建一個MyView的,測試將創建一個TestableMyView並設置其屬性mockNavigationController

這個模擬可以是任何事情,只要它響應-pushViewController:animated:並記錄參數。下面是一個簡單的例子,用手工:

@interface MockNavigationController : NSObject 
@property (nonatomic) int pushViewControllerCount; 
@property (nonatomic, strong) UIViewController *pushedViewController; 
@property (nonatomic) BOOL wasPushViewControllerAnimated; 
@end 

@implementation MockNavigationController 

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated 
{ 
    self.pushViewControllerCount += 1; 
    self.pushedViewController = viewController; 
    self.wasPushViewControllerAnimated = animated; 
} 

@end 

最後,這裏有一個測試:

- (void)testOnSettingsButton_ShouldPushSettingsViewController 
{ 
    // given 
    MockNavigationController *mockNav = [[MockNavigationController alloc] init]; 
    TestableMyView *sut = [[TestableMyView alloc] init]; 
    sut.mockNavigationController = mockNav; 

    // when 
    [sut onSettingsButton]; 

    // then 
    XCTAssertEquals(1, mockNav.pushViewControllerCount); 
    XCTAssertTrue([mockNav.pushedViewController isKindOfClass:[SettingsViewController class]]); 
} 

這些東西可以通過使用模擬對象的框架,如OCMock,OCMockito,或獼猴桃的嘲笑被簡化。但我認爲這有助於先從手開始,以便理解這些概念。然後選擇有幫助的工具。如果你知道如何手工完成,你永遠不會說:「嘲笑框架X不能做我需要的東西!我被困住了!」

+0

謝謝喬恩。我希望從主控制器獲取navigationControl,獲取按鈕(navigationItem.rightBarButtonItem)並向它發送一個新聞報道。然後檢查當前可見的控制器是settingsViewController。我不知道如何按下按鈕。我可以在代碼中找到它。我想重點是我不想檢查按鈕按鈕的作品。我假設它,我只是想檢查正確的控制器出現。那麼,我在控制器上使用onSettingsButton的程度還不夠?感謝您的耐心等待 ! –

+1

不要測試實際的按鈕按下。相反,1)測試按鈕連接,2)它的目標是'onSettingsButton',並且3)直接調用'onSettingsButton'。不需要更多,因爲您不需要測試Apple的代碼。 ...您的測試取決於推送視圖控制器的實際活動,這可能很慢。在測試結束之前甚至可能不會生效,因爲這是一個實際的UI更改。另外你的測試將你綁定到'tipViewController'。 ......但即使它有效,我也希望你看到依賴注入和嘲弄的一般方法。它會爲你服務。 –

+0

你在做什麼'[sut onSettingsButton]'? –

1

找到了一種方法。也許有其他人..

- (void)testSettingsViewShowsWhenSettingsButtonIsClicked{ 
    [self.tipViewController onSettingsButton]; 
    id temp = self.tipViewController.navigationController.visibleViewController; 
    XCTAssertEqual([temp class], [SettingsViewController class], @"Current controller should be Settings view controller"); 
} 

首先調用onSettingsButton,這與點擊按鈕相同,但不是真的。也許這個簡單的測試案例可以嗎?如何模擬實際的新聞?

然後從tipviewcontoller獲取當前視圖,該視圖是應用程序的rootview並檢查它是否爲SettingsViewController。

+0

嗨,我用你的代碼爲swift,但我的導航控制器總是返回零,你能解釋爲什麼嗎? Objective C也會發生這種情況嗎? –