Модульный тест для класса ViewModel с отложенной загрузкой - PullRequest
2 голосов
/ 13 марта 2020

Я пытаюсь написать модульный тест для моего класса viewModel, который загружается медленно. У меня следующий класс ViewModel:

abstract class DetailViewModel(item: TmdbItem) : BaseViewModel() {

    private val _trailers = MutableLiveData<List<Video>>()
    val trailers: LiveData<List<Video>>
        get() = _trailers

    private val _cast: MutableLiveData<List<Cast>> by lazy {
        MutableLiveData<List<Cast>>().also {
            arrayOf(composeObservable { getTrailers(item.id) }
                    .subscribe({ videos ->
                        _trailers.postValue(videos)
                    }) { throwable -> Timber.e(throwable) }
                    , composeObservable { getCast(item.id) }
                    .subscribe({ cast ->
                        _cast.postValue(cast)
                    }) { throwable -> Timber.e(throwable) }).also { compositeDisposable.addAll(*it) }
        }
    }
    val cast: LiveData<List<Cast>>
        get() = _cast

    protected abstract fun getTrailers(id: Int): Observable<List<Video>>

    protected abstract fun getCast(id: Int): Observable<List<Cast>>
}

Я написал для него модульный тест следующим образом:

RunWith(MockitoJUnitRunner::class)
class DetailViewModelTest {

    @get:Rule
    var rule: TestRule = InstantTaskExecutorRule()

    @Mock
    private lateinit var api: TmdbApi

    @Test
    fun loadTrailersAndCast() {
        val observableResponseVideo = Observable.just(TmdbApi.VideoWrapper(
                listOf(Video("id", "name", "site", "key", 20, "type"))))
        `when`(api.movieTrailers(1)).thenReturn(observableResponseVideo)

        val observableResponseCast = Observable.just(TmdbApi.CastWrapper(
                listOf(Cast("char", "name", null, 1))))
        `when`(api.movieCast(1)).thenReturn(observableResponseCast)

        val viewModel = MovieDetailViewModel(api, Movie(1, "overview", "2012", null,
                null, "title", 9.0))

        val observer = LoggingObserver<List<Cast>>()
        viewModel.cast.observeForever(observer)

        val observer2 = LoggingObserver<List<Video>>()
        viewModel.trailers.observeForever(observer2)

        with(observer.value) {
            assertThat(this, `is`(notNullValue()))
            assertTrue(this!!.isNotEmpty())
            assertThat(this.size, `is`(1))
        }

        with(observer2.value) {
            assertThat(this, `is`(notNullValue()))
            assertTrue(this!!.isNotEmpty())
            assertThat(this.size, `is`(1))
        }
    }

    /**
     * simple observer that logs the latest value it receives
     */
    private class LoggingObserver<T> : Observer<T> {
        var value: T? = null
        override fun onChanged(t: T?) {
            this.value = t
        }
    }
}

При выполнении теста я получаю следующую ошибку:

*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844



java.lang.StackOverflowError
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at io.reactivex.Observable.subscribe(Observable.java:12034)
    at io.reactivex.Observable.subscribe(Observable.java:12016)
    at io.reactivex.Observable.subscribe(Observable.java:11945)
    at com.sample.android.tmdb.ui.detail.DetailViewModel$_cast$2.invoke(DetailViewModel.kt:25)
    at com.sample.android.tmdb.ui.detail.DetailViewModel$_cast$2.invoke(DetailViewModel.kt:12)
    at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
    at com.sample.android.tmdb.ui.detail.DetailViewModel.get_cast(DetailViewModel.kt)
    at com.sample.android.tmdb.ui.detail.DetailViewModel.access$get_cast$p(DetailViewModel.kt:12)
    at com.sample.android.tmdb.ui.detail.DetailViewModel$_cast$2$$special$$inlined$also$lambda$4.accept(DetailViewModel.kt:26)
    at com.sample.android.tmdb.ui.detail.DetailViewModel$_cast$2$$special$$inlined$also$lambda$4.accept(DetailViewModel.kt:12)

Знаете ли вы, как я могу устранить ошибку?

Полный исходный код можно найти по адресу: https://github.com/Ali-Rezaei/TMDb-Paging

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...