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?
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.
And then, when creating the presenter whithin the tests