【问题标题】:How to test properties of class using TDD?如何使用 TDD 测试类的属性?
【发布时间】:2012-12-20 15:49:26
【问题描述】:

为什么当我在第 43 行使用方法 respondsToSelector:instancesRespondToSelector: 时,我无法绕过 STAssertTrue?

//我的测试用例代码

- (void)testApiClass {
    //Check object
    NSString* classKey = @"Api";
    id obj = NSClassFromString(classKey);
    STAssertNotNil(obj, [NSString stringWithFormat:@"Model '%@' not found.", classKey]);
    //Check properties
    NSArray* properties =
    @[
        @"performSyncRequestWithUri::",
        @"performAsyncRequestWithUri:::",
    ];
    for (NSString* property in properties) {
        SEL propertySel = NSSelectorFromString(property);
        BOOL isRespondsToSel = [obj respondsToSelector:propertySel];
        STAssertTrue(isRespondsToSel, [NSString stringWithFormat:@"Property '%@' not found on object of class name '%@'", property, [obj class]]);
    }    
}


@interface Api : NSObject

- (NSDictionary*)performSyncRequestWithUri:(NSString *)requestUri params:(NSDictionary *)params;
- (void)performAsyncRequestWithUri:(NSString *)requestUri params:(NSDictionary *)params completionHandler:(void (^)(NSDictionary *, NSError *))completionBlock;

@end

【问题讨论】:

  • “第 43 行”没有行号
  • "performSyncRequestWithUri::" "performAsyncRequestWithUri:::" 你真的有这样命名的方法吗?我对此表示高度怀疑。按照惯例,我们通常不会使用空关键字创建方法
  • Sorry line 43 在这种情况下表示下一行:BOOL isRespondsToSel = [obj respondsToSelector:propertySel];
  • 我真的有这个方法。你可以在我的帖子下面找到接口(我有实现)
  • 这不是 TDD。编写一个复杂的测试(使用 for 循环!)来证明一个对象符合它的接口有什么意义? Xcode 会在没有测试的情况下告诉你。相反,为一项功能编写一个简单的小测试。

标签: objective-c tdd respondstoselector


【解决方案1】:

properties 数组中的字符串常量与Api 接口中的选择器不匹配。

此外,这些选择器都没有引用属性。一个属性有两个选择器:一个getter,比如stringValue,它没有冒号;一个setter,比如setStringValue:,它有一个冒号并且(通常)以set开头。

不要将选择器嵌入到字符串中,而是创建一个选择器数组:

SEL selectors[] = {
    @selector(performSyncRequestWithUri:params:),
    @selector(performAsyncRequestWithUri:params:completionHandler:),
    NULL
};

for (size_t i = 0; selectors[i]; ++i) {
    SEL selector = selectors[i];
    BOOL respondsToSelector = [obj respondsToSelector:selector];
    STAssertTrue(respondsToSelector, [NSString stringWithFormat:
        @"Object %@ doesn't respond to selector %s",
        obj, sel_getName(selector)]);
}

这里的优点是 Xcode 会为您自动完成选择器,您可以通过命令单击选择器来跳转到它们的定义。

【讨论】:

    【解决方案2】:

    这些方法被称为performAsyncRequestWithUri:params:completionHandler:performSyncRequestWithUri:params:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-08
      • 1970-01-01
      • 2011-11-16
      • 2021-12-13
      • 1970-01-01
      • 2015-10-10
      • 1970-01-01
      相关资源
      最近更新 更多