Reputation: 75
I have mock interactor and router for unit tests on presenter presenter method:
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)
}
And test
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])
}
And results are empty,
This test work correctly only when I remove these lines from presenterMethod
.subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
.observeOn(MainScheduler.instance)
I tried with XCTestExpectation and fulfill in do(onNext:{}) block and get the same results, work only without subscribeOn background. Method work correct on device and simulator, presenterMethod is treggered on switch and emit correct events. How this test should be written to work with SubscribeOn background?
Upvotes: 4
Views: 2088
Reputation: 13651
You'll actually want the schedulers passed to subscribeOn
to be a configurable variable on the presenter.
Because tests are better ran synchronously, passing the test scheduler in will ensure there's no need to wait for an asynchronous execution.
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)
}
}
And then, when creating the presenter whithin the tests
let presenter = Presenter(backgroundScheduler: self.scheduler, mainScheduler: self.scheduler)
Upvotes: 3