Android MVVM架构中如何测试ViewModel中的LiveData对象?
校验LiveData取值的实现方法
首先你需要先补充对应的测试配置(如果还没添加的话):
- 导入
androidx.arch.core:core-testing测试库,用来支持LiveData的同步执行逻辑 - 在测试类中添加
InstantTaskExecutorRule规则,让LiveData的观察者回调可以同步执行,不需要额外切换线程
具体的测试逻辑调整如下:
- 先mock
dataRepository.getCharacters()的固定返回值 - 调用
fetchCharacters触发ViewModel逻辑 - 直接对
charactersLiveData的取值做断言,也可以通过注册Observer捕获值后再断言
你可以直接修改现有测试用例,也可以单独拆分不同场景的测试,示例代码如下:
@RunWith(MockitoJUnitRunner::class) class MainActivityViewModelTest { @get:Rule val coroutineRule = MainCoroutineRule() // 新增LiveData同步执行规则 @get:Rule val instantTaskExecutorRule = InstantTaskExecutorRule() @Mock private lateinit var dataRepository: DataRepository @InjectMocks private lateinit var mainActivityViewModel: MainActivityViewModel @Test fun `fetchCharacters调用时触发Repository调用`() = runBlockingTest { val testData = Result.success(arrayListOf<Character>()) `when`(dataRepository.getCharacters()).thenReturn(testData) mainActivityViewModel.fetchCharacters() verify(dataRepository).getCharacters() } @Test fun `fetchCharacters返回成功结果时LiveData取值正确`() = runBlockingTest { // 构造测试用的返回数据 val testCharacterList = arrayListOf( Character(id = 1, name = "测试角色1"), Character(id = 2, name = "测试角色2") ) val mockSuccessResult = Result.success(testCharacterList) // mock Repository的返回值 `when`(dataRepository.getCharacters()).thenReturn(mockSuccessResult) // 触发请求 mainActivityViewModel.fetchCharacters() // 断言LiveData的取值和mock返回值一致 assertEquals(mockSuccessResult, mainActivityViewModel.charactersLiveData.value) } }
如果你的LiveData需要捕获多次发射的值,可以用observeForever注册观察者来收集所有值,示例如下:
val capturedValues = mutableListOf<Result<ArrayList<Character>>>() val observer = Observer<Result<ArrayList<Character>>> { capturedValues.add(it) } mainActivityViewModel.charactersLiveData.observeForever(observer) // 执行业务逻辑 mainActivityViewModel.fetchCharacters() // 断言捕获到的值 assertEquals(1, capturedValues.size) assertEquals(mockSuccessResult, capturedValues.first()) // 测试完成后主动移除观察者避免内存泄漏 mainActivityViewModel.charactersLiveData.removeObserver(observer)
需要补充的额外测试用例
你当前的测试只覆盖了Repository被调用的场景,还需要补充以下测试:
- 成功场景测试:Repository返回成功结果时,LiveData正确接收对应的成功Result值
- 失败场景测试:Repository返回失败Result/抛出异常时,LiveData正确接收对应的异常信息,不会出现崩溃
- 多次调用测试:重复调用fetchCharacters时,LiveData每次都会更新为最新的返回值,不会出现旧值残留的问题
内容的提问来源于stack exchange,提问作者BRDroid
相关产品推荐
相关产品推荐

