Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 方法内部的单元测试RxJava+改型调用_Android_Unit Testing_Mockito_Retrofit2_Rx Java2 - Fatal编程技术网

Android 方法内部的单元测试RxJava+改型调用

Android 方法内部的单元测试RxJava+改型调用,android,unit-testing,mockito,retrofit2,rx-java2,Android,Unit Testing,Mockito,Retrofit2,Rx Java2,我要测试的方法包含对改装服务的两个调用: internal fun poll(): Completable { return presenceService.askForFrequency(true).toObservable() .flatMap { it -> Observable.interval(it.frequency, TimeUnit.SECONDS, Schedulers.io()) } .flatMapComple

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

 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
}
单元测试运行的日志包括:

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调用时,test停止工作,mock只被调用一次

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

谢谢!但是,如果我在间隔调用中添加RxJavaPlugins.setComputationSchedulerHandler{scheduler}或指定Schedulers.io,它也不起作用。虽然设置起来可能很麻烦,但我自己的经验是将间隔、延迟、去盎司操作符将运行的时间传递给调度器。它使测试更容易。
 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)
}