我正在尝试在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/