我想测试的方法包含对改装服务的两次调用:
cleartool mklabel MY_LABEL TestFile.txt@@\main\1
internal fun poll(): Completable {
return presenceService.askForFrequency(true).toObservable()
.flatMap { it -> Observable.interval(it.frequency, TimeUnit.SECONDS, Schedulers.io()) }
.flatMapCompletable { _ -> presenceService.sendHeartbeat() }
.subscribeOn(Schedulers.io())
.retry()
}
是在课程中注入的,所以我提供了一个模拟的测试:
presenceService
检查调用val frequency = PublishSubject.create<Presence>()
val heartbeat = PublishSubject.create<Unit>()
val mockPresenceService = mock<PresenceService> {
on { askForFrequency(any()) } doReturn frequency
on { sendHeartbeat() } doReturn heartbeat
}
方法的测试是否正常,但是检查轮询请求发送的测试从不起作用:
askForFrequency
单元测试运行的日志是:
@Test
fun presenceService_sentHeartbeat() {
RxJavaPlugins.setIoSchedulerHandler { scheduler }
frequency.onNext(Presence(1)) //polls with 1s interval
heartbeat.onNext(Unit)
presenceMaintainer.onActivityResumed(any())
scheduler.advanceTimeBy(2, TimeUnit.SECONDS)
verify(mockPresenceService).askForFrequency(true) //works correctly
verify(mockPresenceService).sendHeartbeat() //never works
}
问题是:如何测试第二种方法(Wanted but not invoked:
presenceService.sendHeartbeat();
However, there was exactly 1 interaction with this mock:
presenceService.askForFrequency(true);
)也被调用(可能多次)?
同时我发现问题在于第二个flatmap,因为此方法的测试正常工作(验证该方法被调用了60次):
sendHeartbeat
但是当我将调用的顺序更改为 internal fun pollTest(): Observable<Presence> {
return Observable.interval(1, TimeUnit.SECONDS, Schedulers.io())
.subscribeOn(Schedulers.io())
.flatMap { it -> presenceService.askForFrequency(true).toObservable() }
}
@Test
fun presenceService_sentHeartbeat() {
frequency.onNext(Presence(1))
val result = arrayListOf<Unit>()
presenceMaintainer.pollTest().subscribe({ t -> result.add(Unit) })
Thread.sleep(60*1000)
println(result.size)
verify(mockPresenceService, Times(60)).askForFrequency(true)
}
时,测试停止工作,并且只调用一次mock。
答案 0 :(得分:1)
默认情况下,Observable.interval()
在计算调度程序上运行,而不在io调度程序上运行。这意味着,2秒等待将实时运行,因此您的测试将在调用sendHeartBeat()
之前完成2秒。