首页 > 解决方案 > 为 RxJava doOnSubscribe 和 doOnFinally 情况编写测试用例

问题描述

假设我在 Kotlin 中有这段特殊的代码。我的问题是如何在订阅期间进行测试我已将按钮的可见性设置为 VISIBLE 并将文本设置为“”。一旦订阅完成,我就可以看到 GONE 并测试“DONE”。

fun getInfo() {
    getInfoFromApi()
        .doOnSubscribe {
            buttonVisibility.set(View.VISIBLE)
            buttonText.set(“”)
         }
        .onFinally {
            buttonVisibility(View.GONE)
            buttonText.set(“DONE”)
        }
        .subscribe {
            // Some other random stuff
        }
    }
}

截至目前,我的测试用例看起来像这样。

@Test
fun getInfo() {
    viewModel.getInfo()
    Assert.assertEquals(View.GONE, viewModel.buttonVisibility.get())
    Assert.assertEquals(“DONE”, viewModel.buttonText.get())
}

当您查看最终状态应该是什么时,这显然是正确的,但是我如何测试 doOnSubscribe 的中间阶段?

如果按钮文本从“”设置为 DONE,并且可见性从 VISIBLE 变为 GONE,是否有断言的方法?

标签: androidjunitmockitorx-java

解决方案


doOnSubscribe并且onFinally只是View/的状态ViewModel,因此您可以提取这些状态并检查状态更改:

fun getInfo() {
    getInfoFromApi()
        .doOnSubscribe {
            view.setButtonVisible()
         }
        .onFinally {
            view.setButtonGone()
        }
        .subscribe {
            // Some other random stuff
        }
    }
}

然后验证调用:

@Test
fun getInfo() {
    val view = mock(View::class)
    viewModel.getInfo()
    verify(view, times(1)).setButtonVisible())
    verify(view, times(1)).setButtonGone())
}

顺便说一句,如果您的示例应该与一起使用,MVVM那么您ViewModel不应该参考View. ViewModel应该为视图提供绑定。然后代码可能如下所示:

fun getInfo():Observable<State> {
    return concat(
       just(State.Progress), 
       getInfoFromApi().map(State.Result)
    ).onErrorResumeNext(just(State.Error))
}

然后测试变得更加抽象和清晰

@Test
fun getInfoSuccess() {
    //config api success behaviour
    TestObserver<State> observer = TestObserver.create();
    viewModel.getInfo().subscribe(observer)
    observer.assertResult(State.Progress, State.Result);
}

@Test
fun getInfoError() {
    //config api error behaviour
    TestObserver<State> observer = TestObserver.create();
    viewModel.getInfo().subscribe(observer)
    observer.assertResult(State.Progress, State.Error);
}

推荐阅读