1

最近我阅读了很多关于 Swift 运行时的内容,并且对使用静态方法调度优化我的代码越来越感兴趣。这发生在以下方法中:

  • 结构方法
  • final 类方法,即用 final 关键字声明为私有或在 final 类中
  • 在协议扩展中定义的协议方法,而不在协议本身中声明。

问题是,这些情况都不能让我编写可测试的代码,至少不是我现在这样做的方式:在单元测试中注入被模拟替换的协议实体。

那么,是否有可能在不放弃静态方法分派的情况下编写可测试的代码,如果可以,如何去做呢?

谢谢!

4

1 回答 1

2

泛型是您要寻找的。您可以通过协议进行抽象,但编译器仍然知道您使用的确切类型,因此不需要动态调度。

protocol Dependency {
  func doSomething()
}

struct RealDependency: Dependency {
  func doSomething() {
    print("I'm doing real work")
  }
}

struct MockDependency: Dependency {
  func doSomething() {
    print("I'm the mock, so I do nothing")
  }
}

struct MyApp<D: Dependency> {
  let dependency: D

  func doSomething() {
    dependency.doSomething()
  }
}

let myAppReal = MyApp(dependency: RealDependency())
let myAppMock = MyApp(dependency: MockDependency())

myAppReal.doSomething() // Prints "I'm doing real work"
myAppMock.doSomething() // Prints "I'm the mock, so I do nothing"

但是,请注意,在 Swift 中,泛型单态化并不能保证。所以无论如何你可能会以某种形式的动态调度结束。看到这个链接

于 2018-11-07T14:27:10.393 回答