I have a LiveData
variable that I want to assign a value to after receiving a response from a HTTP request
. I assign this value inside the launch {}
scope. However, when I test the code to see that the value has actually been assigned, the test fails stating that the value is null
.
I have tried another option which is to use runBlocking {}
scope instead of launch {}
scope and my test case passes. The library used for networking is Retrofit
Below is the code that uses launch()
and makes the test case fail.
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")
}
}
}
Below is the code that uses runBlocking()
and makes the test case pass.
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")
}
}
}
Why is the launch()
not assigning the value to the LiveData
variable?
I have also tried making executeRequest
a suspend
function like below
private suspend fun executeRequest(params){
}
and also this
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"))
}
}
}
}
########
This is the test
val viewModel = MyViewModel(fakeClientRepository)
val observer = Observer<State> {}
try {
viewModel.state.observeForever(observer)
assert(viewModel.state.value == StateSuccess("success"))
} finally {
viewModel.state.removeObserver(observer)
}
```