簡體   English   中英

方法內部單元測試RxJava + Retrofit調用

[英]Unit testing RxJava + Retrofit call inside the method

我要測試的方法包含兩次對改造服務的調用:

 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 )是否也被調用(可能多次)

同時,我發現問題出在第二個平面圖中,因為對此方法的測試正常進行(驗證該方法被調用了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的調用askForFrequency -> map to interval -> map each tick to poll call ,測試停止工作,並且模擬僅被調用一次。

默認情況下, Observable.interval()在計算調度程序上運行,而不是在io調度程序上運行。 這意味着2秒鍾的等待將實時運行,因此您的測試將在調用sendHeartBeat()之前2秒完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM