2016-12-12 2 views
3

Скажем, у меня есть Field класс с harvest функции, как это:подклассов RxSwift/Реактивная расширение для гася

class Field { 

    func harvest(handler: (Vegetable) -> Void) { 
     … 
     handler(carrot) 
     … 
     handler(potato) 
     … 
     handler(carrot) 
     … 
    } 
} 

У меня также есть Реактивная версия/API для одной и той же функции:

import RxSwift 

extension Reactive where Base: Field { 

    func harvest() -> Observable<Vegetable> { 
     return Observable.create { observer in 
      self.base.harvest(handler: observer.onNext) 

      return Disposables.create() 
     } 
    } 
} 

Для целей тестирования я создал подкласс Field с именем MockField, который переопределяет harvest(:), чтобы вызвать обработчик с набором заштрихованных Vegetable с. При использовании объекта MockField, такого как field.harvest(:), все работает отлично, и я получаю оштукатуренные овощи.

Теперь я хочу сделать то же самое с Reactive extension, чтобы звонить на field.rx.harvest, но я не могу переопределить его, чтобы вернуть окутанные овощи! Как я могу переопределить функции в пространстве имен rx?

ответ

1

Вероятно, самый простой способ сделать это будет не подклассов, но определение harvest() -> Observable<Vegetable> в терминах Field.harvest(handler:)

import RxSwift 

extension Reactive where Base: Field { 

    func harvest() -> Observable<Vegetable> { 
     return Observable.create { observer in 
      self.base.harvest(handler: observer.onNext) 

      return Disposables.create() 
     } 
    } 
} 

Действовать таким образом, вы не должны поддерживать две реализации harvest.

PS: Блок, переданный в одноразовый, должен отменить действие, а не отправить завершенное событие. Если нет возможности отменить harvest(handler:), вы можете просто вернуть Disposables.create().

+0

Спасибо за комментарий! Именно так я это делаю, ссылаясь на базовую реализацию, но я не писал ее так, как в примере (моя ошибка, я ее обновлю). Однако проблема все еще существует. Как вы переопределите реализацию 'rx.harvest()' во время тестирования, чтобы вернуть stubbed 'Vegetable'? Я думаю, что это невозможно переопределить, поскольку это Reactive extension. Одно из решений заключалось бы в расширении 'Field' с помощью' rx_harvest' (а не 'rx.harvest'), поэтому я могу переопределить его для тестирования, но затем я потеряю группу Reactive. Есть предположения? –

+0

С приведенной выше реализацией вы должны уже иметь значения 'MockVegetable' в наблюдаемых, если они используются как' MockField(). Rx.harvest() ', правильно? Кроме того, что происходит при выполнении расширений Reactive где base: MockField {func harvest() -> Observable {/ * ... * /}} '? – tomahh

+0

Я делаю 'extension Reactive где base: MockField {func harvest() -> Observable {return Observable.from ([Vegetable, ...])}}', чтобы вернуть окутанный 'Vegetable', и я добавляю' MockField' для класса, который его использует. Однако, поскольку 'MockField' не переопределяет' rx.harvest' поля ',' mock-реализация никогда не вызывается. –

Смежные вопросы