Swift: переопределение инициализатора, который принимает NSInvocation

Я пытаюсь создать повторно используемую тестовую обвязку в 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 пытается запустить FooPrimeTests, он не вызывает 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.

Есть ли обходной путь?


person David Moles    schedule 30.06.2014    source источник
comment
Я с той же проблемой!   -  person Andy    schedule 20.07.2014
comment
В качестве обходного пути, возможно, вы можете попробовать издеваться над своим объектом. Вы сможете перенаправить вызов инициализации.   -  person Pintouch    schedule 16.10.2014


Ответы (1)


Я не уверен, правильно ли я понял, но при проверке кода, который вы предложили, вы должны получить ошибку компилятора, например:   введите здесь описание изображения

Что на самом деле я считаю вполне нормальным, поскольку ваши FooPrimeTests просто подклассифицируют XCTestCase, который имеет другую инициализацию, например:

init!(invocation: NSInvocation!)

init!(selector: Selector)

init()

Вероятно, когда вы опубликовали вопрос, вы используете более старую версию Swift (в настоящее время я использую ее на Xcode Beta 6.2), поэтому вы не видите ошибку. Но, и я повторяю еще раз, если я правильно понял вашу точку зрения, ваш класс FooPrimeTests не может видеть ваш пользовательский инициализатор только потому, что он подклассифицирует XCTestCase, а не FooTestHarness. В каком классе определен init(instance: Foo).

Поэтому вы, вероятно, захотите определить FooPrimeTests как подкласс FooTestHarness. Таким образом, вы сможете правильно увидеть свой инициализатор. Надеюсь, это поможет.

person DennyLou    schedule 19.11.2014