我尝试对使用 Kotlin 协程进行改造 API 调用的 ViewModel 进行单元测试。单元测试失败,出现空指针异常。
当使用 Retrofit RXJAva UnitTest Passes 进行相同尝试时。使用 Mockito 框架。
请检查我的代码并让我知道我的代码中出现的错误。
请在下面找到 ViewModel 和 UnitTest 类文件:
fetchResponseFromAPI()方法进行 API 调用以获取数据
RetroCoroutineViewModel.kt:
class RetroCoroutineViewModel : ViewModel(),LifecycleObserver{
private val errorOnAPI = MutableLiveData<String>()
private val mutableLiveData:MutableLiveData<List<RetroRxModel>> = MutableLiveData()
var loading : MutableLiveData<Boolean> = MutableLiveData()
@Inject
lateinit var retrofit: Retrofit
lateinit var apiService: APIService
init {
DaggerRetroRxComponent.create().inject(this)
loading.value = true
apiService = retrofit.create(APIService::class.java)
}
val postsMutableLiveData:MutableLiveData<List<RetroRxModel>> = MutableLiveData()
**@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun fetchResponseFromAPI(){**
viewModelScope.launch {
try{
val response = apiService.fetchUserPosts()
if(response.isSuccessful){
postsMutableLiveData.postValue(response.body())
loading.value = false
}else{
loading.value = false
errorOnAPI.postValue("Something went wrong::${response.message()}")
}
}catch (e:Exception){
loading.value = false
errorOnAPI.postValue("Something went wrong::${e.localizedMessage}")
}
}
}
fun fetchPostLiveData(): LiveData<List<RetroRxModel>> = postsMutableLiveData
override fun onCleared() {
super.onCleared()
}
fun fetchError(): LiveData<String> = errorOnAPI
fun fetchLoadStatus():LiveData<Boolean> = loading
private fun onError(message: String){
errorOnAPI.value = message
loading.value = false
}
}
RetroCoroutineViewModelTest:
@RunWith(MockitoJUnitRunner::class)
@ExperimentalCoroutinesApi
class RetroCoroutineViewModelTest {
@get:Rule
val testInstantTaskExecutorRule: TestRule = InstantTaskExecutorRule()
@get:Rule
val testCoroutineRule = TestCoroutineRule()
@Mock
lateinit var retrofit: Retrofit
@Mock
lateinit var apiService: APIService
lateinit var retroCoroutineViewModel: RetroCoroutineViewModel
private lateinit var response: Response<List<RetroRxModel>>
private var loading: Boolean = false
@Before
fun setUp(){
MockitoAnnotations.initMocks(this)
}
@Test
fun fetchRetroInfoTest_success(){
retroCoroutineViewModel = RetroCoroutineViewModel()
testCoroutineRule.runBlockingTest {
var retroRxModel = RetroRxModel("tile", "body", "1")
var retroRXModelList = ArrayList<RetroRxModel>()
retroRXModelList.add(retroRxModel)
response = Response.success(retroRXModelList)
if (retrofit != null) {
if (apiService != null) {
Mockito.`when`(apiService.fetchUserPosts()).thenReturn(response)
retroCoroutineViewModel.fetchResponseFromAPI()
}
}
val funResponse = retroCoroutineViewModel.fetchPostLiveData()
println("Response::::${funResponse.value}")
Assert.assertEquals(1,funResponse.value?.size)
Assert.assertEquals(loading,retroCoroutineViewModel.loading)
}
}
}
当我尝试运行单元测试用例时,我观察到以下异常:
java.lang.AssertionError:预期:1 实际:null
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:144)
at com.rxretrofit.RetroCoroutineViewModelTest$fetchRetroInfoTest_success$1.invokeSuspend(RetroCoroutineViewModelTest.kt:75)
构建.Gradle:
testImplementation "org.mockito:mockito-core:3.3.3"
testImplementation 'androidx.arch.core:core-testing:2.1.0'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.4'