我有一个 LiveData
变量,我想在收到来自 HTTP 请求
的响应后为其赋值。我在 launch{}
范围内分配这个值。但是,当我测试代码以查看实际已分配值时,测试失败并指出该值为 null
。
我尝试了另一种选择,即使用 runBlocking {}
范围而不是 launch {}
范围,并且我的测试用例通过了。用于网络的库是 Retrofit
下面是使用 launch()
并使测试用例失败的代码。
private var _state = MutableLiveData<State>()
val state: LiveData<State>
get() = _state
private var job = Job()
private val uiScope = CoroutineScope(job + Dispatchers.Main)
init {
executeRequest(....)
}
// Test cases fails with this function
private fun executeRequest(params) {
uiScope.launch {
val deferred = repository.getApi()
.requestAsync(params)
try {
val response = deferred.await()
_state.value = StateSuccess(response)
} catch (e: Exception) {
_state.value = StateError("Failure: $e.message")
}
}
}
下面是使用 runBlocking()
并使测试用例通过的代码。
private var _state = MutableLiveData<State>()
val state: LiveData<State>
get() = _state
private var job = Job()
private val uiScope = CoroutineScope(job + Dispatchers.Main)
init {
executeRequest(....)
}
// Test cases passes with this function
private fun executeRequest(params) {
runBlocking {
val deferred = repository.getApi()
.requestAsync(params)
try {
val response = deferred.await()
_state.value = StateSuccess(response)
} catch (e: Exception) {
_state.value = StateError("Failure: $e.message")
}
}
}
这是测试用例
val viewModel = MyViewModel(fakeClientRepository)
val observer = Observer<State> {}
try {
viewModel.state.observeForever(observer)
assert(viewModel.state.value == StateSuccess("success"))
} finally {
viewModel.state.removeObserver(observer)
}
为什么 launch()
没有将值分配给 LiveData
变量?
最佳答案
尝试使用 Dispatchers.IO
调度程序,然后将值分配给 LiveData
,使用 postValue()
而不是 value
即
private fun executeRequest(params) {
uiScope.launch {
withContext(Dispatcher.IO){
val deferred = repository.getApi()
.requestAsync(params)
try {
val response = deferred.await()
_state.postValue(RESPONSE)
} catch (e: Exception) {
_state.postValue(StateError("Failure: $e.message"))
}
}
}
}
关于android - 使用 launch() 范围时无法为 LiveData 变量赋值,但可以使用 runBlocking() 为 LiveData 赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59081832/