【问题标题】:Is it possible to check if a UI element has a certain reference outlet?是否可以检查 UI 元素是否具有某个参考插座?
【发布时间】:2012-08-26 08:07:15
【问题描述】:

我正在编写单元测试来查找某个笔尖上是否存在元素。例如,我想遍历一个 nibs 视图并检查是否存在一个引用出口“commentTextView”,以检查该文本视图是否存在。

现在,我只看到检查目标是否存在的方法(例如检查按钮是否会在单击时调用某个选择器),而不是检查我需要什么。

【问题讨论】:

  • “引用出口”由 Xcode 在它们引用的对象上列出。如果您的文本视图旨在确定它是否被某个出口引用,那么您已经知道文本视图存在。
  • @PeterHosey 假设我有一个带有 3 个按钮的视图。我想检查是否有登录、注册和帮助按钮。检查 UIButton 的存在没有帮助。我认为检查是否有 3 个按钮也是没用的。我想做的是检查是否存在链接到 loginButton、registerButton 和 helpButton 的现有按钮。这将验证有 3 个按钮,并且它们执行应执行的操作(相信这些引用执行了代码中应执行的操作)。
  • 大概您的网点连接到“文件所有者”,或者笔尖中的某个根对象?您能否获取该对象,遍历您尝试测试的 outlet,并验证它们的存在、唯一性和其他属性?
  • 嘿,你有没有找到任何解决方案或框架?
  • 不。我在 UIView 上创建了一个类别,通过它们的属性(按钮的目标/操作、标签的文本等)检查某些元素的存在。因此,如果我想检查视图中是否存在“Hello”标签,我会执行[self.view hasLabelWithText: @"Hello"]; 之类的操作。不是最好的解决方案,但这就是我现在正在使用的。

标签: objective-c xcode cocoa iboutlet


【解决方案1】:

不要检查他们是否有出口,而是为他们分配一个唯一的标签。选择 Interface Builder 中的按钮,然后转到右侧的 Attributes Inspector。朝向底部应该是一个框来设置对象的标签属性。然后,当您逐步浏览 nib 的视图时,您可以检查每个标签并使用它来确定它是什么视图。

【讨论】:

    【解决方案2】:

    我在这里做了几个假设,所以如果我是基地,请告诉我。

    1) 您有一个将连接插座的对象列表,以及这些插座的列表。 (例如,文件的所有者是一个MyViewController 类,并具有出口viewlabelbutton 等;有一个UITableView 具有出口delegatedataSource 等)

    2) 您的 nib 旨在使查找 1 中的所有对象变得切实可行。例如,如果某些 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 nib 很大程度上基于键值编码,我认为在测试 nib 方面有很多潜力可以探索,不管它的价值是什么。我没有处理从笔尖中的对象发送的操作,因为我必须下车学习,但我会分享我到目前为止所做的。

    这是我在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
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-09
      • 2012-07-13
      • 2020-07-09
      相关资源
      最近更新 更多