快速将可测试代码与静态方法分派结合起来

时间:2018-11-06 21:07:35

标签: swift function dispatch testability

我最近已经阅读了很多有关Swift的运行时的内容,并且对使用静态方法分派来优化代码越来越感兴趣。使用以下方法会发生这种情况:

  • 结构方法
  • 最终类方法,即使用final关键字声明的私有方法或最终类方法
  • 在协议扩展中定义的
  • 协议方法,无需在协议本身中声明。

问题是,在所有这些情况下,问题都不使我能够编写可测试的代码,至少不能像现在这样进行:注入在单元测试中由模拟替换的协议实体。

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

谢谢!

1 个答案:

答案 0 :(得分: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中,无法保证泛型的单态化。因此,您可能以某种形式的动态调度结束。参见this link