RxSwift TestScheduler не работает, если подписаться на фоне
У меня есть фиктивный интерактор и маршрутизатор для модульных тестов по методике презентатора:
private func presenterMethod(_ isOn: Bool) -> Driver<Bool> {
return interactor.interactorMethod(isOn)
.subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
.observeOn(MainScheduler.instance)
.do(onError: { [weak self] error in
self?.view.showError(error)
})
.asDriver(onErrorJustReturn: !isOn)
}
И проверить
func testPresenterMethod() {
let trigger = self.scheduler.createHotObservable([
next(100, (false)),
next(200, (true)),
next(300, (false))
]).asDriverOnErrorJustComplete()
let observer = scheduler.createObserver(Bool.self)
let input = createInput(presenterTrigger: trigger)
let output = presenter.transform(input)
scheduler.scheduleAt(0, action: {
output.presenterMethodOutput.asObservable()
.subscribe(observer)
.disposed(by: self.disposeBag)
})
scheduler.start()
let results = observer.events.map {
$0.value.element
}
XCTAssertEqual(results, [false, true, false])
}
И результаты пусты,
Этот тест работает правильно, только когда я удаляю эти строки из PresenterMethod
.subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
.observeOn(MainScheduler.instance)
Я попытался с XCTestExpectation и выполнить в блоке do(onNext:{}) и получить те же результаты, работать только без подписки на фон. Метод корректно работает на устройстве и симуляторе, PresenterMethod переключается на коммутатор и выдает правильные события. Как этот тест должен быть написан для работы с фоном SubscribeOn?
1 ответ
Вы действительно хотите, чтобы планировщики были переданы subscribeOn
быть настраиваемой переменной на докладчике.
Поскольку тесты лучше выполнять синхронно, передача планировщика тестов гарантирует, что нет необходимости ждать асинхронного выполнения.
struct Presenter {
let mainScheduler: SchedulerType
let backgroundScheduler: SchedulerType
init(backgroundScheduler: SchedulerType = ConcurrentDispatchQueueScheduler(qos: .background), mainScheduler: SchedulerType = MainScheduler.instance) {
self.mainScheduler = mainScheduler
self.backgroundScheduler = backgroundScheduler
}
private func presenterMethod(_ isOn: Bool) -> Driver<Bool> {
return interactor.interactorMethod(isOn)
.subscribeOn(backgroundScheduler)
.observeOn(mainScheduler)
.do(onError: { [weak self] error in
self?.view.showError(error)
})
.asDriver(onErrorJustReturn: !isOn)
}
}
А потом, при создании докладчика в рамках тестов
let presenter = Presenter(backgroundScheduler: self.scheduler, mainScheduler: self.scheduler)