我正在尝试对依赖于 Objective-C 类的 Swift 类进行单元测试。称这些为
SwiftClass
和 ObjcClass
。
我创建了一个协议,其中包含
ObjcClass
所需的 SwiftClass
的方法/属性。我创建了一个实现这些方法和属性的存根(称之为 ObjcClassMock
)。所以我尝试这样做:
// ObjcClass is in its own .m and .h files somewhere...
// In Swift:
@objc protocol ObjcClassProtocol {
func doStuff()
}
class ObjcClassMock: ObjcClassProtocol {
func doStuff() { /* sike, actually do nothing */ }
}
class SwiftClass {
let objcClass: ObjcClassProtocol
// default to ObjcClass's singleton for compatibility with older code
init(objcClass: ObjcClassProtocol = ObjcClass.shared()) { ... }
}
// In tests:
func testSwiftClass() {
let swiftClass = SwiftClass(objcClass: ObjcClassMock())
}
现在的问题是
ObjcClass
并不隐式符合这个新协议,即使它确实包含协议所需的所有方法和属性,我认为这是有道理的。强制将其强制转换为 any ObjcClassProtocol
在运行时会崩溃(Could not cast value of type ObjcClass to ObjcClassProtocol
- 我想这也是有道理的)。
据我所知,我有几个选择:
ObjcClass
明确地符合 ObjcClassProtocol
。我对 Objective-C 不太熟悉,所以我可能在这里遗漏了一些东西,但这看起来很重要。特别是,它似乎需要将协议方法分离到它们自己的块中。 ObjcClass
也用在其他地方,除了这些特定方法恰好需要 SwiftClass
之外,没有什么可以将它们组合在一起,所以我不想这样做。 (项目结构一团糟,但它就是这样。)如果这是 Swift,我可以只将 class ObjcClass: ObjcClassProtocol
添加到 ObjcClass
的声明中,而不改变任何其他内容。我可以在 Objective-C 中做类似的事情吗?感觉就像我找错了树。我对 Swift 和 Objective-C 之间的互操作还很陌生,所以感觉好像我遗漏了一些明显的东西。当然有更简单的方法来做我想做的事吗?
我只是在 Swift 扩展中声明 ObjcClass 一致性:
extension ObjcClass: ObjcClassProtocol {
func doStuff() {
}
}
注意:不要忘记在桥接头文件中添加 ObjcClass.h,以便 Swift 可以看到