2012-08-31 88 views
5

我正在編寫單元測試,以查找某個筆尖上是否存在元素。例如,我想遍歷一個nibs視圖並檢查是否存在引用出口'commentTextView',以檢查該文本視圖是否存在。是否可以檢查UI元素是否具有某個參考插座?

現在,我只看到方法來檢查目標是否存在(比如檢查按鈕是否會在點擊時調用某個選擇器),但不檢查我需要的東西。

+0

「引用插座」由Xcode在它們引用的對象上列出。如果您有文本視圖以確定它是否被某個插座引用,那麼您已經知道文本視圖存在。 –

+0

@PeterHosey讓我們說我有一個3按鈕的視圖。我想檢查是否有登錄,註冊和幫助按鈕。檢查UIButton的存在並沒有幫助。我會爭辯說,檢查有3個按鈕也是沒用的。我想要做的是檢查是否有現有的按鈕鏈接到loginButton,registerButton和helpButton。這將驗證有3個按鈕,並且他們按照他們應該做的(相信這些引用在代碼中執行它們應該做的事)。 –

+1

推測你的插座連接到「文件所有者」,或者筆尖中的一些根對象?你能否得到這個對象,遍歷你試圖測試的網點,並驗證它們的存在性,唯一性和其他屬性? –

回答

0

而不是檢查,看他們是否有一個插座,分配給他們所有的唯一標籤。選擇Interface Builder中的按鈕並轉到右側的屬性檢查器。接近底部應該是一個框來設置對象的標籤屬性。然後,當您逐步瀏覽筆尖的視圖時,您可以檢查每個標籤並使用它來確定它的視圖。

0

我在這裏做了一些假設,所以如果我是基地,讓我知道。

1)您有一個將連接插座的物體列表以及這些插座的列表。 (例如,文件的所有者是一個MyViewController類和具有網點viewlabelbutton,等等;還有一個UITableView帶插座delegate,並dataSource等)

2)你的筆尖設計,使其實用例如,如果一些UIControl沒有被頂級對象或代理對象引用,則它已被賦予標籤值以使其易於用viewWithTag:

假設這些都是真的,那麼你可以通過基本上做下面的事情來測試一個筆尖被加載(在僞代碼中)

for each referencingObject in nibObjects 
{ 
    for each outletName in referencingObject.outletNames 
    { 
     assertExistence(/* is an object referenced by this outlet? */) 
     assertProperties(/* does the object conform to the properties expected for this referencing object/outlet pairing? */) 
    } 
} 

我開始刺穿這個實現。由於iOS筆尖很大程度上依賴於鍵值編碼,我認爲在測試筆尖時有很多潛力可以探索,以及它的價值。我沒有處理從筆尖中的對象發送的動作,因爲我必須離開並學習,但我會分享我迄今爲止所做的。

下面是測試方法的代碼我在SenTestCase子類中寫道:

ViewController *vc = [[ViewController alloc] init]; 
UINib *nib1 = [UINib nibWithNibName:@"ViewController1" bundle:nil]; 
NSArray *topLevelObjects = [nib1 instantiateWithOwner:vc options:nil]; 

ReferencingObject *filesOwnerReferencingObject = [[ReferencingObject alloc] init]; 
filesOwnerReferencingObject.object = vc; 

//Make a referenced object outlet for the view 
ReferencedOutlet *viewOutlet = [[ReferencedOutlet alloc] init]; 
viewOutlet.name = @"view"; 
viewOutlet.propertyAssertionBlock = ^(id object) { 
    UIView *theView = (UIView *)object; 
    STAssertEquals(1.0f, theView.alpha, @"shouldn't have any transparency"); 
}; 

//Make a referenced object outlet for the label 
ReferencedOutlet *labelOutlet = [[ReferencedOutlet alloc] init]; 
labelOutlet.name = @"label"; 
labelOutlet.propertyAssertionBlock = ^(id object) { 
    UILabel *theLabel = (UILabel *)object; 
    NSString *expectedLabelText = @"ViewController1.xib"; 
    STAssertTrue([expectedLabelText isEqualToString:theLabel.text], nil); 

}; 

filesOwnerReferencingObject.outlets = @[ viewOutlet, labelOutlet ]; 


NSArray *referencingObjects = @[ filesOwnerReferencingObject ]; 
for (ReferencingObject *referencingObject in referencingObjects) 
{ 
    for (ReferencedOutlet *outlet in referencingObject.outlets) 
    { 
     id object = [filesOwnerReferencingObject.object valueForKey:outlet.name]; 
     STAssertNotNil(object, nil); 
     outlet.propertyAssertionBlock(object); 
    } 
} 

這裏是我的接口/執行ReferencingObjectReferencedOutlet類。

@interface ReferencingObject : NSObject 

@property (nonatomic, strong) id object; 
@property (nonatomic, strong) NSArray *outlets; 

@end 

@implementation ReferencingObject 
@end 

typedef void (^ReferencedOutletPropertyAssertionBlock)(id); 

@interface ReferencedOutlet : NSObject 

@property (nonatomic, copy) NSString *name; 
@property (nonatomic, copy) ReferencedOutletPropertyAssertionBlock propertyAssertionBlock; 

@end 

@implementation ReferencedOutlet 
@end 

希望這個答案會對你或其他人有所幫助。如果您有任何問題,請告訴我。