简体   繁体   English

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

[英]RxJava unit testing - Observable not emitting events in tests

I'm testing a view model which has the following definition: 我正在测试具有以下定义的视图模型:

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

My fragment then displays the post author by subscribing to viewModel.postAuthor in its onActivityCreated and calling and subscribing to refresh() whenever the user wants an updated post and everything is fine and dandy. 然后,我的片段通过在其onActivityCreated订阅viewModel.postAuthor ,并在用户想要更新的帖子并且一切正常且viewModel.postAuthor时调用并订阅refresh()来显示帖子作者。

The issue I'm running into is trying to verify this behaviour in a unit test: specifically, I am unable to get postAuthor to emit an event in my testing environment. 我遇到的问题是试图在单元测试中验证此行为:具体地说,我无法让postAuthor在我的测试环境中发出事件。

My test is defined as follows: 我的测试定义如下:


    @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" }
        }

The test fails due to no values or errors being emitted, even though I can verify through the debugger that the mock does in-fact return the Post as expected. 由于没有发出任何值或错误,因此测试失败,即使我可以通过调试器验证该模拟确实按预期返回了Post Is there something obvious that I'm missing, or am I completely wrong in my testing approach? 有什么明显的我想念的地方吗?还是我的测试方法完全错误?

viewModel.postAuthor is a hot-observable. viewModel.postAuthor是可热观察的。 It emits value when you call _post.onNext(it) . 当您调用_post.onNext(it)时,它会发出值。

Unlike a cold-observable, the late subscribers cannot receive the values that got emitted before they subscribe. 与冷观测不同,晚期订阅者无法接收在订阅之前发出的值。 So in your case I think the viewModel.postAuthor is subscribed after you call viewModel.refresh() , so it cannot receive the value. 因此,在您的情况下,我认为在调用viewModel.refresh()之后, viewModel.postAuthor进行预订,因此它无法接收该值。

The observable could be emitting on a different thread so that's why it's empty when the test is checking the values/errors. 可观察对象可能在另一个线程上发出,因此这就是为什么在测试检查值/错误时它为空的原因。

You could try forcing your observable to emit on the same thread. 您可以尝试强制将可观察对象发射到同一线程上。 Depending on which scheduler you're using, it'd be something like: 根据您使用的调度程序,它可能是这样的:

RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM