Модульное тестирование RxJava - Наблюдаемые неиспускающие события в тестах - PullRequest
0 голосов
/ 28 марта 2019

Я тестирую модель представления, которая имеет следующее определение:

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() всякий раз, когда пользователь хочет обновить сообщение, и все в порядке.

Проблема, с которой я сталкиваюсь, заключается в попытке проверить это поведение в модульном тесте: в частности, я не могу заставить 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 ]

3 голосов
/ 06 мая 2019

viewModel.postAuthor - наблюдаемая в горячем состоянии.Он выдает значение, когда вы звоните _post.onNext(it).

В отличие от наблюдаемых в холодном режиме, поздние подписчики не могут получить значения, которые были получены до подписки.Так что в вашем случае я думаю, что viewModel.postAuthor подписывается после того, как вы позвоните viewModel.refresh(), поэтому он не может получить значение.

0 голосов
/ 28 марта 2019

Наблюдаемое может быть отправлено в другой поток, поэтому оно пустое, когда тест проверяет значения / ошибки.

Вы можете попытаться заставить свой наблюдаемый излучать в том же потоке. В зависимости от того, какой планировщик вы используете, это будет что-то вроде:

RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() }
...