单位测试RXJAVA 在方法内进行了改装调用



我要测试的方法包含两个调用改造服务的调用:

 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);

问题是:如何测试第二种方法(sendHeartbeat(也被调用(可能几次(

同时,我发现问题在于第二个flatmap,因为该方法的测试正常工作(验证该方法称为60次(:

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

但是,当我将呼叫的顺序更改为 askForFrequency -> map to interval -> map each tick to poll call时,测试停止工作,模拟仅被调用一次。

默认情况下,Observable.interval()在计算调度程序上运行,而不是IO调度程序。这意味着,2秒等待将实时运行,因此您的测试将在致电sendHeartBeat()之前完成2秒。

相关内容

  • 没有找到相关文章

最新更新