使用switchmap时,如何对Room数据源进行单元测试?

时间:2019-05-29 12:00:36

标签: android unit-testing

我有这段代码可以初始化Room的数据源,实际上它是在表中搜索特定的关键字,并创建一个分页列表发送回viewmodel:

@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)
}

要注意的另一件事是Scheduler变量,该变量又被注入并包含将要使用的调度程序,对于实际应用程序,它们是Schedulers.io()和AndroidSchedulers.mainThread(),而在测试中它们都是调度程序。蹦床()

所以我写了下面的测试来检查它是否可以工作(我手动检查了上面的代码,它确实可以工作,但是我想在上面添加单元测试)

@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)
}

我的问题是,即使在我调用logic.initialize()之后直接调用了initialize方法中的代码(因此,如果我调用verify(db).loadReportHeaders(“”)也可以)我所编写的代码通过逻辑运行。setListFilter(filter)似乎不会触发切换图中的更改,因此即使我使用Thread.sleep

,测试verify(db).loadReportHeaders(filter)始终会失败。

我在做什么错了,我该如何解决?

0 个答案:

没有答案