【问题标题】:RxJava unit testing - Observable not emitting events in testsRxJava 单元测试 - Observable 在测试中不发射事件
【发布时间】:2019-03-28 16:18:45
【问题描述】:

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

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

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

我遇到的问题是尝试在单元测试中验证此行为:具体来说,我无法让 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。是否有明显的遗漏,或者我的测试方法完全错误?

【问题讨论】:

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


    【解决方案1】:

    viewModel.postAuthor 是一个热可观察对象。当您调用 _post.onNext(it) 时,它会发出值。

    与cold-observable 不同,迟到的订阅者无法接收在订阅之前发出的值。 所以在你的情况下,我认为viewModel.postAuthor 在你调用viewModel.refresh() 后被订阅,所以它不能接收到值。

    【讨论】:

      【解决方案2】:

      observable 可能在不同的线程上发射,所以当测试检查值/错误时它是空的。

      你可以尝试强制你的 observable 在同一个线程上发射。根据您使用的调度程序,它会是这样的:

      RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多