Swift:覆盖采用NSInvocation的初始化程序

Dav*_*les 9 nsinvocation swift

我正在尝试在Swift中创建一个可重用的测试工具,其想法是子类将扩展测试工具以提供测试中的实例,并且可以添加他们自己的子类特定的测试方法,如下所示:

class FooTestHarness: XCTestCase {
  let instance: Foo

  init(instance: Foo) {
    self.instance = instance
  }

  func testFooBehavior() {
    XCTAssert(instance.doesFoo())
  }
}

class FooPrime: Foo {
  func doesFooPrime(): Bool { /* ... */ }
}

class FooPrimeTests: XCTestCase {

  init() {
    super.init(FooPrime())
  }

  func myInstance(): FooPrime {
    return instance as FooPrime
  }

  func testFooPrimeBehavior() {
    XCTAssert(myInstance().doesFooPrime())
  }

}
Run Code Online (Sandbox Code Playgroud)

但是,当XCode的testrunner尝试运行时FooPrimeTests,它不会调用no-arg init(),它会调用init(invocation: NSInvocation!)(并且因为没有调用而失败).我试图覆盖这个FooTestHarness:

  init(invocation: NSInvocation!, instance: Foo) {
    self.instance = instance
    super.init(invocation)
  }
Run Code Online (Sandbox Code Playgroud)

并在FooPrimeTests:

  init(invocation: NSInvocation!) {
    super.init(invocation, FooPrime())
  }
Run Code Online (Sandbox Code Playgroud)

但是这个消息失败了'NSInvocation' is unavailable.

有解决方法吗?

小智 1

我不确定我是否正确,但检查您建议的代码,您应该得到一个编译器错误,例如: 在此输入图像描述

实际上我认为这很正常,因为您的 FooPrimeTests 只是 XCTestCase 的子类,它具有不同的 init,例如:

init!(invocation: NSInvocation!)

init!(selector: Selector)

init()
Run Code Online (Sandbox Code Playgroud)

可能当你发布时你会问你正在旧版本的 Swift 上运行(我目前在 Xcode Beta 6.2 上运行它),这就是你看不到错误的原因。但是,我再说一遍,如果我的观点是正确的,您的类 FooPrimeTests 无法看到您的自定义初始化程序,只是因为子类化了 XCTestCase,而不是 FooTestHarness。这是定义 的类init(instance: Foo)

因此,您可能希望将 FooPrimeTests 定义为 FooTestHarness 的子类。这样你应该能够正确地看到你的初始化程序。希望这有帮助。