RxJava 2 mock Observable не работает
Я использую RxJava 2 Observable
обернуть сканер штрих-кода в одном из моих приложений. Этот фрагмент показывает, как я подписываюсь на Observable
и слушать его события
override fun start() {
disposables.addAll(subscribeToBarcodeReader(), loadUser())
}
private fun subscribeToBarcodeReader(): Disposable {
return barcodeObservable
.subscribeOn(bgScheduler)
.observeOn(mainScheduler)
.subscribeBy(
onNext = { barcode -> saveBarcode(barcode) },
onComplete = { Log.d(TAG, "Barcode observable complete") },
onError = { e -> Log.d(TAG, "Barcode observable error", e) }
)
}
barcodeObservable
является объектом Observable<Barcode>
тип. Все это отлично работает на реальном устройстве с реальным сканером штрих-кода. Теперь я хочу провести модульное тестирование saveBarcode()
метод и попытаться высмеять Observable<Barcode>
сюда
@RunWith(MockitoJUnitRunner::class)
class OrbFoldersPresenterTests {
@Mock
private lateinit var jobService: FolderJobService
private val bgScheduler = TestScheduler()
private val mainScheduler = TestScheduler()
private val barcodeObservable: Observable<Barcode> = Observable.just(Barcode(
"2500020109205", LocalDateTime.now().toString()))
@Mock
private lateinit var userStore: UserStore
@Mock
private lateinit var prefs: Preferences
@Mock
private lateinit var barcodeService: BarcodeReadService
@Test
fun testBarcodeSave() {
val jobId = 201804040001
val disposables = CompositeDisposable()
whenever(userStore.authorizedUser()).thenReturn(Maybe.just(User()))
val presenter = OrbFoldersPresenter(jobId, jobService, disposables, bgScheduler,
mainScheduler, barcodeObservable, userStore, prefs, barcodeService)
presenter.start()
}
}
Я ожидаю, что когда я позвоню presenter.start()
ведущий должен подписаться на barcodeObservable
и получить onNext()
событие с объектом, который я предоставил. Но этого не происходит. Что я делаю неправильно?
2 ответа
TestScheduler
полезно, если вам нужно проверить синхронизацию с вашими потоками. Поскольку ваша единственная задача в реализации должна состоять в том, чтобы запустить поток синхронно, вам лучше использовать Schedulers.trampoline()
вместо. Это тогда вызовет подписку и наблюдение без изменения потока.
Там происходит асинхронная обработка из-за подписки и наблюдения на заданных планировщиках. onNext()
не вызывается синхронно, как ожидается вашим тестовым кодом.
С TestScheduler
Вы можете, например, позвонить triggerActions()
или же advanceTimeBy()
выполнить асинхронный код.