我正在尝试在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())
  }

}

但是,当XCode的testrunner尝试运行FooPrimeTests时,它没有调用no-arg init(),而是调用了init(invocation: NSInvocation!)(并且由于没有一个而失败)。我试图在FooTestHarness中覆盖它:
  init(invocation: NSInvocation!, instance: Foo) {
    self.instance = instance
    super.init(invocation)
  }

并在FooPrimeTests中:
  init(invocation: NSInvocation!) {
    super.init(invocation, FooPrime())
  }

但这失败,并显示消息'NSInvocation' is unavailable

有解决方法吗?

最佳答案

我不确定我是否正确,但是请检查您建议的代码,您应该得到编译器错误,例如:

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

init!(invocation: NSInvocation!)

init!(selector: Selector)

init()

可能是在发布时,您质疑您是在旧版本的Swift上运行(我目前正在Xcode Beta 6.2上运行它),这就是为什么您看不到错误的原因。但是,我再说一次,如果我说对了,您的类FooPrimeTests就不会看到您的自定义初始化程序,这是因为它先订阅了XCTestCase,然后又订阅了FooTestHarness。定义init(instance: Foo)的类。

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

关于Swift:覆盖采用NSInvocation的初始化程序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24499387/

10-16 19:26