【问题标题】:How can I test live data object in Android MVVM如何在 Android MVVM 中测试实时数据对象
【发布时间】:2021-11-01 08:31:24
【问题描述】:

您好,我正在尝试测试我的视图模型中的 livedata,我已编写测试以验证是否已进行存储库调用

在这种情况下如何检查实时数据对象,以及我应该在 viewModel 中为这段代码编写哪些额外的测试用例

谢谢 回复

MainActivityViewModel

class MainActivityViewModel @Inject constructor(
    private val dataRepository: DataRepository
): ViewModel() {
    val _charactersLiveData = MutableLiveData<Result<ArrayList<Character>>>()
    val charactersLiveData: LiveData<Result<ArrayList<Character>>> = _charactersLiveData

    fun fetchCharacters() {
        viewModelScope.launch {
            _charactersLiveData.value = dataRepository.getCharacters()
        }
    }
}

MainActivityViewModelTest

@RunWith(MockitoJUnitRunner::class)
class MainActivityViewModelTest {

    @get:Rule
    val coroutineRule = MainCoroutineRule()

    @Mock
    private lateinit var dataRepository: DataRepository

    @InjectMocks
    private lateinit var mainActivityViewModel: MainActivityViewModel

    @Test
    fun fetchCharacters() {
        runBlockingTest {
            mainActivityViewModel.fetchCharacters()
            verify(dataRepository).getCharacters()
        }
    }
}

【问题讨论】:

  • 如果 LiveData 引用了存储库,那么我将验证模拟中的函数是否被调用,您已经完成了。需要注意的一点是 ViewModel 应该将 Dispatcher 注入到构造函数中,这样您就可以在测试中使用 Main.Dispatcher 以便结果同步返回。
  • 你能分享一个这样的例子吗
  • 这个免费课程有一个专门用于测试的广泛部分。它还展示了如何测试LiveDataudacity.com/course/advanced-android-with-kotlin--ud940

标签: android unit-testing kotlin mvvm android-viewmodel


【解决方案1】:

您可以参考这篇文章:https://medium.com/androiddevelopers/unit-testing-livedata-and-other-common-observability-problems-bb477262eb04

这里的主要思想是:

  • 模拟dataRepository
  • dataRepository 调用getCharacters() 时,应该返回测试值。例如。 listOf('a')
  • 执行mainActivityViewModel.fetchCharacters()
  • 期待实时数据的价值
assertEquals(mainActivityViewModel.charactersLiveData.getOrAwaitValue(), listOf('a'))

【讨论】:

    【解决方案2】:

    如果有任何问题,请尝试此操作,然后告诉我。我已经尝试根据您的课程和数据进行操作,但如果您需要,可以更改。

    @RunWith(MockitoJUnitRunner::class)
    class MainActivityViewModelTest {
    
    @get:Rule
    val coroutineRule = MainCoroutineRule()
    
    @Mock
    private lateinit var dataRepository: DataRepository
    
    @InjectMocks
    private lateinit var mainActivityViewModel: MainActivityViewModel
    
    @Mock
    private lateinit var dataObserver:  Observer<Result<List<Character>>>
    
    @Test
    fun fetchCharacters() {
        runBlockingTest {
            Mockito.`when`(datarepository).getcharacter()
            .thenreturn(Result.success(listOf(Character (
            Name=A,
            Type=hero))))
    mainActivityViewModel.fetchCharacters()
    mainActivityViewModel.charactersLiveData.observeForever(dataObserver)
    Mockito.verify(dataRepository).getCharacters()
    Mockito.verify(dataObserver).onChanged(Result.success(listOf(Character (
      Name=A,
      Type=hero))))
    mainActivityViewModel.charactersLiveData.removeObserver(dataObserver)
                }
            }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2020-05-25
      • 2016-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-08
      • 1970-01-01
      • 2014-11-30
      相关资源
      最近更新 更多