我有这段代码可以初始化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)始终会失败。我在做什么错了,我该如何解决?