将扩展名标记为@objc仅用于单元测试

时间:2019-08-29 18:10:15

标签: ios objective-c swift unit-testing

我有一个在目标c中声明的类,如下所示:

@interface Person : NSObject

@property (nonatomic, readonly) NSString* firstName;
@property (nonatomic, readonly) NSString* lastName;

@end

我在Swift中声明了一个扩展名,以获取Person的全名:

extension Person {
    var fullName: String {
      return "\(firstName) \(lastName)"
    } 
}

我想编写单元测试,在这里我想使用扩展名测试人员的全名。因此,我创建了一个模拟子类,并覆盖了fullName属性。但是,为此,我必须使用@objc关键字将扩展暴露给目标c运行时。

有没有办法仅将扩展名标记为@objc才用于单元测试目标?标记扩展是否对编译/运行时产生“重大”影响?

我尝试添加Swift编译时标志,例如:

#if UNIT_TEST_TARGET_RUNNING
@objc
#endif

但是会导致编译时错误。任何建议都欢迎! 请注意,示例已简化以解决问题,并且无法更改目标c接口。

1 个答案:

答案 0 :(得分:0)

标记扩展名是否对编译/运行时产生“重大”影响?

不是。编译器会产生一个thunk,这是一个调用您的Swift方法的Objective C方法。这就是ObjC运行时中注册的东西,这就是它所看到的全部。除其他外,它可以与Swift通用货币类型以及对象C中使用的通用货币类型进行转换。

如果要继承并覆盖该属性,请继续执行该操作。真的没什么大不了的。

或者,您可以将类的接口提取到协议中,并在“真实”实现中符合该协议,并创建一个测试double来模拟所有测试方法。