如何使用Koin对MVVM进行单元测试?
我尝试测试:link
但是,我不知道为什么我在ViewModelTest中得到error("No Data in ViewModel")
fun getLookUpLeagueList()
资料库
class LookUpLeagueRepository {
fun getLookUpLeague(idLeague: String): MutableLiveData<LookUpLeague> {
val lookUpLeague = MutableLiveData<LookUpLeague>()
APIService().getLookUpLeague(idLeague).enqueue(object : Callback<LookUpLeague> {
override fun onFailure(call: Call<LookUpLeague>, t: Throwable) {
d("TAG", "lookUpLeagueOnFailure ${t.localizedMessage}")
}
override fun onResponse(call: Call<LookUpLeague>, response: Response<LookUpLeague>) {
lookUpLeague.value = response.body()
}
})
return lookUpLeague
}
}
View 模型
class LookUpLeagueViewModel(private val lookUpLeagueRepository: LookUpLeagueRepository) :
ViewModel() {
var lookUpLeagueList = MutableLiveData<LookUpLeague>()
fun getLookUpLeagueList(idLeague: String) {
lookUpLeagueList = lookUpLeagueRepository.getLookUpLeague(idLeague)
}
}
模块
val lookUpLeagueModule = module {
single { LookUpLeagueRepository() }
viewModel { LookUpLeagueViewModel(get()) }
}
ViewModel测试
class LookUpLeagueViewModelTest : KoinTest {
val lookUpLeagueViewModel: LookUpLeagueViewModel by inject()
val idLeague = "4328"
@get:Rule
val rule = InstantTaskExecutorRule()
@Mock
lateinit var observerData: Observer<LookUpLeague>
@Before
fun before() {
MockitoAnnotations.initMocks(this)
startKoin {
modules(lookUpLeagueModule)
}
}
@After
fun after() {
stopKoin()
}
@Test
fun getLookUpLeagueList() {
lookUpLeagueViewModel.lookUpLeagueList.observeForever(observerData)
lookUpLeagueViewModel.getLookUpLeagueList(idLeague)
val value = lookUpLeagueViewModel.lookUpLeagueList.value ?: error("No Data in ViewModel")
Mockito.verify(observerData).onChanged(value)
}
}
最佳答案
@Test
fun getLookUpLeagueList() {
lookUpLeagueViewModel.lookUpLeagueList.observeForever(observerData)
...
}
此时
lookUpLeagueList
是MutableLiveData
的实例。说这是MutableLiveData #1
。lookUpLeagueViewModel.getLookUpLeagueList(idLeague)
执行上面的行将调用
LookUpLeagueViewModel.getLookUpLeagueList
函数。让我们看看里面。lookUpLeagueList = lookUpLeagueRepository.getLookUpLeague(idLeague)
在
MutableLiveData
内创建了一个全新的LookUpLeagueRepository
。这与observerData
所观察到的不同。此时lookUpLeagueViewModel.lookUpLeagueList
引用了新的MutableLiveData #2
,因为您已将其重新分配给var lookUpLeagueList
。val value = lookUpLeagueViewModel.lookUpLeagueList.value ?: error("No Data in ViewModel")
因此,您实际上是在查询
MutableLiveData #2
,它是新的,未观察到的并且为空。这就是value
是null
的原因。不要将其声明为var
,而应将其设置为val
。不要重新分配变量setValue
或postValue
来传播更改。