2012-08-31 90 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 

希望这个答案会对你或其他人有所帮助。如果您有任何问题,请告诉我。