如何从 Swift 代码模拟 Objective-C 类以进行单元测试?

问题描述 投票:0回答:1

我正在尝试对依赖于 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 和 Objective-C 之间的互操作还很陌生,所以感觉好像我遗漏了一些明显的东西。当然有更简单的方法来做我想做的事吗?

swift objective-c
1个回答
0
投票

我只是在 Swift 扩展中声明 ObjcClass 一致性:

extension ObjcClass: ObjcClassProtocol {
    func doStuff() {
    
    }
}

注意:不要忘记在桥接头文件中添加 ObjcClass.h,以便 Swift 可以看到

© www.soinside.com 2019 - 2024. All rights reserved.