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() выполнить асинхронный код.

Другие вопросы по тегам