RxJava单元测试-可观察的在测试中不发出事件

时间:2019-03-28 16:18:46

标签: android kotlin junit rx-java rx-java2

我正在测试具有以下定义的视图模型:

class PostViewModel(private val postApi: PostApi): ViewModel() {

    private val _post: PublishSubject<Post> = PublishSubject.create()
    val postAuthor: Observable<String> = _post.map { it.author }

    fun refresh(): Completable {
        return postApi.getPost() // returns Single<Post>
            .doOnSuccess {
                _post.onNext(it)
            }
            .ignoreElement()
        }
    }
}

然后,我的片段通过在其viewModel.postAuthor中订阅onActivityCreated并在用户想要更新的帖子并且一切正常且繁琐时调用并订阅refresh()来显示帖子作者。 / p>

我遇到的问题是试图在单元测试中验证此行为:具体地说,我无法在测试环境中获得postAuthor来发出事件。

我的测试定义如下:


    @Test
        fun `When view model is successfully refreshed, display postAuthor`() {


        val post = Post(...)


        whenever(mockPostApi.getPost().thenReturn(Single.just(post))
            viewModel.refresh()
                .andThen(viewModel.postAuthor)
                .test()
                .assertValue { it == "George Orwell" }
        }

由于没有发出任何值或错误,因此测试失败,即使我可以通过调试器验证该模拟确实按预期返回了Post。是否有明显的遗漏之处,或者我的测试方法完全错误?

2 个答案:

答案 0 :(得分:2)

viewModel.postAuthor是热门话题。当您调用_post.onNext(it)时,它会发出值。

与冷观测不同,晚期订阅者无法接收在订阅之前发出的值。 因此,在您的情况下,我认为viewModel.postAuthor是在您调用viewModel.refresh()之后订阅的,因此它无法接收该值。

答案 1 :(得分:0)

observable可能在另一个线程上发出,这就是为什么在测试检查值/错误时它为空的原因。

您可以尝试强制将可观察对象发射到同一线程上。根据您使用的调度程序,它会像这样:

RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() }