JUnit 5测试-无法观察嵌套的LiveData值

问题描述 投票:0回答:1

概述

Expected-将嵌套的LiveData值保存在本地单元测试中,然后声明它们的值。

Observed-在生产代码中成功观察到将嵌套LiveData值保存在ViewModel中,但是在本地单元测试中失败。这可能是由于本地单元测试与在Android环境上运行相比缺少线程。

代码

  • ViewModel包含用户选择要打开的内容时的LOADINGCONTENTERROR(LCE)条件。
  • 保存LiveData NotifyItemChangedEffect状态以更新视图。
  • NotifyItemChangedEffect保存在函数内部,以保存发送到视图的内容。 CONTENT条件下,所选项目被发送到保存有LiveData对象ContentToPlay的视图。
  • 在生产中,这适用于在LOADINGCONTENTERROR期间视图的UI更新,而在成功ContentToPlay条件下返回[[only CONTENT

ContentViewModel.kt

is ContentSelected -> { _feedViewState.value = _feedViewState.value?.copy( // LiveData value for ContentToPlay initiated here. contentToPlay = switchMap(getAudiocast(contentSelected)) { lce -> liveData { when (lce) { is Loading -> _viewEffect.value = _viewEffect.value?.copy( notifyItemChanged = liveData { emit(Event(NotifyItemChangedEffect(...))) }) is Lce.Content -> { _viewEffect.value = _viewEffect.value?.copy( notifyItemChanged = liveData { emit(Event(NotifyItemChangedEffect(...))) }) // LiveData value for ContentToPlay saved here. emit(Event(lce.packet)) } is Error -> { _viewEffect.value = _viewEffect.value?.copy( notifyItemChanged = liveData { emit(Event(NotifyItemChangedEffect(...))) }) _viewEffect.value = _viewEffect.value?.copy( snackBar = liveData { emit(Event(SnackBarEffect(...))) }) } } } }) ... }
  • 通过设计
-在ContentToPlayLOADING条件下不返回ERROR
  • 问题
  • -NotifyItemChangedEffect的嵌套LiveData值未保存在单元测试中,该单元测试会在每个LCE条件下更新视图。该代码在为ContentToPlay保存的LiveData内部执行。该模式已记录并在生产中工作。

    PlayContentTests.kt

    @ExtendWith(InstantExecutorExtension::class) class PlayContentTests { @ParameterizedTest @MethodSource("FeedLoad") fun `Play Content`(test: PlayContentTest) = runBlocking { // ViewModel method included to initiate ContentSelected event. ... when (test.lceState) { LOADING -> assertThat(contentViewModel.viewEffect.getOrAwaitValue().notifyItemChanged.getOrAwaitValue().peekEvent()).isEqualTo( NotifyItemChangedEffect(...)) CONTENT -> { assertThat(contentViewModel.feedViewState.getOrAwaitValue().contentToPlay.getOrAwaitValue().peekEvent()).isEqualTo( ContentToPlay(...)) assertThat(contentViewModel.viewEffect.getOrAwaitValue().notifyItemChanged.getOrAwaitValue().peekEvent()).isEqualTo( NotifyItemChangedEffect(...)) } ERROR -> { assertThat(contentViewModel.feedViewState.getOrAwaitValue().contentToPlay.getOrAwaitValue().peekEvent()).isEqualTo( ContentToPlay(...)) assertThat(contentViewModel.viewEffect.getOrAwaitValue().notifyItemChanged.getOrAwaitValue().peekEvent()).isEqualTo( NotifyItemChangedEffect(...)) } } } }
    android kotlin android-testing android-livedata junit5
    1个回答
    0
    投票
    在所有(LCE)加载,内容,错误条件中保存LiveData

    在ViewModel的所有LCE条件下保存ContentToPlay LiveData值或null,以确保为本地单元测试同步返回值。

    Note-此策略的缺点是,它会在生产代码中不必要地向视图发出ContentToPlay值,这不是理想的,但似乎不是主要问题。

    ContentViewModel.kt

    _feedViewState.value = _feedViewState.value?.copy(contentToPlay = switchMap(getAudiocast(contentSelected)) { lce -> liveData { when (lce) { is Loading -> { setContentLoadingStatus(contentSelected.content.id, View.VISIBLE) _viewEffect.value = _viewEffect.value?.copy( notifyItemChanged = liveData { emit(Event(NotifyItemChangedEffect(contentSelected.position))) }) // Empty ContentToPlay saved. emit(Event(null)) } is Lce.Content -> { setContentLoadingStatus(contentSelected.content.id, View.GONE) _viewEffect.value = _viewEffect.value?.copy( notifyItemChanged = liveData { emit(Event(NotifyItemChangedEffect(contentSelected.position))) }) // ContentToPlay saved. emit(Event(lce.packet)) } is Error -> { setContentLoadingStatus(contentSelected.content.id, View.GONE) _viewEffect.value = _viewEffect.value?.copy( notifyItemChanged = liveData { emit(Event(NotifyItemChangedEffect(contentSelected.position))) }) if (lce.packet.filePath.equals(TTS_CHAR_LIMIT_ERROR)) _viewEffect.value = _viewEffect.value?.copy( snackBar = liveData { emit(Event(SnackBarEffect(TTS_CHAR_LIMIT_ERROR_MESSAGE))) }) else _viewEffect.value = _viewEffect.value?.copy( snackBar = liveData { emit(Event(SnackBarEffect(CONTENT_PLAY_ERROR))) }) // Empty ContentToPlay saved. emit(Event(null)) } } } })
    © www.soinside.com 2019 - 2024. All rights reserved.