我尝试对我的ViewModel进行单元测试,该模型通过LiveData
将一些内容发布回活动中,但是当我运行设置livedata值的方法时,我得到了错误
java.lang.RuntimeException:android.os.Looper中的方法getMainLooper 没有嘲笑。
我已经阅读了几篇帖子和文章,您所要做的就是为Rule
添加一个InstantTaskExecutorRule
,它应该可以正常工作,但是我照做了,但仍然出现错误。
这是我的单元测试
val observer: Observer<String> = mock(Observer::class.java) as Observer<String>
@get:Rule
var rule: TestRule = InstantTaskExecutorRule()
@Test
fun testSearchDataValidationFailureMissingSearchLocation() {
val viewModel = MoveViewModel()
val param1= 0
val param2= 1
val param3= "1234"
viewModel.dialogMessageLiveData.observeForever(observer)
Assert.assertFalse(viewModel.validateSearchData(param1, param2, param3))
verify(observer).onChanged("Data not valid")
}
这是我要测试的方法
fun validateSearchData(param1:Int,param2:Int,param3:String):Boolean{
var valid:Boolean = false
if(param1== 0 || param2== 0 || param3.isBlank()){
dialogMessageLiveData.postValue("Data not valid")
}else{
valid = true
}
return valid
}
我不确定该如何解决,有人可以建议其他解决方案吗?
答案 0 :(得分:2)
您可以使用此扩展来获取 [LiveData] 的值或等待它获得一个值,并超时。在主机端 (JVM) 测试中使用此扩展。建议将其与 InstantTaskExecutorRule
或类似机制一起使用以同步执行任务。
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
fun <T> LiveData<T>.getOrAwaitValue(
time: Long = 2,
timeUnit: TimeUnit = TimeUnit.SECONDS,
afterObserve: () -> Unit = {}
): T {
var data: T? = null
val latch = CountDownLatch(1)
val observer = object : Observer<T> {
override fun onChanged(o: T?) {
data = o
latch.countDown()
this@getOrAwaitValue.removeObserver(this)
}
}
this.observeForever(observer)
try {
afterObserve.invoke()
// Don't wait indefinitely if the LiveData is not set.
if (!latch.await(time, timeUnit)) {
throw TimeoutException("LiveData value was never set.")
}
} finally {
this.removeObserver(observer)
}
@Suppress("UNCHECKED_CAST")
return data as T
}
然后在你的测试用例中你可以得到值
viewModel.dialogMessageLiveData.getOrAwaitValue()