首页 > 解决方案 > 通过单元测试如何在 viewModel 中测试 switchMap 从存储库类调用正确的方法

问题描述

在我的 ViewModel 中,我使用了带有 liveData 变量的 swithcMap 作为参数。当 liveData 变量被设置/更改时,switchMap 会从我的存储库中调用一个方法。我的视图模型代码:

class MainViewModel @Inject constructor(val mainRepository: MainRepository) : ViewModel() {

    var searchQuery:MutableLiveData<SearchQuery> = MutableLiveData()
    var liveResult:MediatorLiveData<My_Result> = MediatorLiveData()


    var apiData:LiveData<My_Result> = Transformations
    .switchMap(searchQuery){query ->
        query?.let {
        val source: LiveData<My_Result> = mainRepository.fetchApiresultFromClient(it.filter_search , it.filter_topics, it.filter_language , it.page_number)

        liveResult.addSource(source){ item->
            liveResult.value = item
            liveResult.removeSource(source)
        }

        source

        }
    }

}

现在我想测试一下是否设置了 searchQuery:

我该怎么做呢?我所能做的就是:

@ExtendWith(InstantExecutorExtension::class)
class MainViewModelTest {

    lateinit var  mainViewModel: MainViewModel

    @Mock
     lateinit var  mainRepository: MainRepository


    @BeforeEach
    fun init()  {
    MockitoAnnotations.initMocks(this)
    mainViewModel = MainViewModel(mainRepository)
    }


    @Test
    @Throws(Exception::class)
    fun setSearchQuery_callsRepositoryMethod() {
    var filter_search: SearchQuery = SearchQuery("java", "","",1)

    }

}

标签: androidunit-testing

解决方案


为了使您的代码更易于测试,您可以将其替换为:

class MainViewModel @Inject constructor(val mainRepository: MainRepository) : ViewModel() {

    val searchQuery:MutableLiveData<SearchQuery> = MutableLiveData()

    var apiData:LiveData<My_Result> = Transformations.switchMap(searchQuery) { query ->
        query?.let {
            mainRepository.fetchApiresultFromClient(it.filter_search , it.filter_topics, it.filter_language , it.page_number)
        }
    }
}

那么你应该

  • 模拟mainRepository.fetchApiresultFromClient返回一个MutableLiveData
  • 称呼mainViewModel.searchQuery.value = Query(...)
  • 并断言当mainRepository发出一个新值时apiData也会发出相同的值。

如果您有一些测试代码要分享,我可以帮助您完成它


推荐阅读