Как вы можете тестировать источник данных Room при использовании switchmaps? - PullRequest
0 голосов
/ 29 мая 2019

У меня есть этот код, который инициализирует источник данных из Room, который фактически выполняет поиск таблицы по определенному ключевому слову и создает список страниц для отправки обратно в модель представления:

@VisibleForTesting()
val mFilter: BehaviorSubject<String> = BehaviorSubject.create()

fun initialize() {
    setListFilter("")
    mFilter.switchMap {
        RxPagedListBuilder<Int, ReportHeaderEntity>(db.loadReportHeaders(it)
            , PagedList.Config.Builder()
                .setInitialLoadSizeHint(PAGE_SIZE)
                .setPageSize(PAGE_SIZE)
                .build())
            .setFetchScheduler(schedulers.subscribeScheduler)
            .setNotifyScheduler(schedulers.observeScheduler)
            .buildObservable()
    }.map {
        @Suppress("UNCHECKED_CAST")
        it as PagedList<ReportHeader>
    }
        .subscribe({
            log?.d(TAG, "applying filter: \"${mFilter.value}\" with results ${it.size}")
            vm.showReports(it)
        }, {
            vm.showError(R.string.error, it.localizedMessage)
        }).addTo(mDisposable)
}

модель представления внедряетсяиспользуя переменную vm, и когда поисковый запрос изменяется, он вызывает этот метод:

fun setListFilter(filter: String) {
    mFilter.onNext(filter)
}

другая вещь, на которую следует обратить внимание, - это переменная планировщиков, которая снова вводится и содержит планировщики, которые будут использоваться для фактического приложения.это Schedulers.io () и AndroidSchedulers.mainThread (), в то время как при тестировании они используются как Schedulers.trampoline ()

, поэтому я написал следующий тест, чтобы проверить его работоспособность (я проверил приведенный выше код вручную иработает, но я хочу добавить к нему модульные тесты)

@Test
fun filterReports() {
    val filter = "12"
    val expected = UnitTestData.REPORT_HEADERS.filter { it.name.contains(filter) || it.description.contains(filter) }.sortedByDescending { it.date }
    val captor = argumentCaptor<PagedList<ReportHeader>>()
    whenever(db.loadReportHeaders(filter)).thenReturn(TestDataSource.TestDataSourceFactory(expected))

    logic.initialize()

    logic.setListFilter(filter)
    Thread.sleep(100)
    verify(db).loadReportHeaders(filter)
    verify(vm).showReports(captor.capture())
    assertEquals(Math.min(expected.size, 20), captor.firstValue.size)
    assertEquals(Math.min(expected.size, 20), expected.intersect(captor.firstValue).size)
    assertEquals(filter, logic.mFilter.value)
}

Моя проблема в том, что хотя код в методе initialize вызывается сразу после того, как я вызываю logic.initialize () (поэтому, если я вызываюпроверить (БД) .loadReportHeaders ("") все будет в порядке) код, который я запускаю через logic.setListFilter (фильтр) некажется, вызывает изменение в карте переключателей, и поэтому тест проверки (db) .loadReportHeaders (filter) всегда терпит неудачу, даже если я использую Thread.sleep

что я делаю неправильно и как я могу это исправить?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...