我正在测试具有以下定义的视图模型:
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
。是否有明显的遗漏之处,或者我的测试方法完全错误?
答案 0 :(得分:2)
viewModel.postAuthor
是热门话题。当您调用_post.onNext(it)
时,它会发出值。
与冷观测不同,晚期订阅者无法接收在订阅之前发出的值。
因此,在您的情况下,我认为viewModel.postAuthor
是在您调用viewModel.refresh()
之后订阅的,因此它无法接收该值。
答案 1 :(得分:0)
observable可能在另一个线程上发出,这就是为什么在测试检查值/错误时它为空的原因。
您可以尝试强制将可观察对象发射到同一线程上。根据您使用的调度程序,它会像这样:
RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() }