當我運行測驗時,我正在為我的視圖模型撰寫單元測驗我得到以下例外
lateinit property apiInterface has not been initialized
kotlin.UninitializedPropertyAccessException: lateinit property apiInterface has not been initialized
at com.yodgorbek.newstask.presentation.viewmodel.BBCNewsViewModelTest.setUp(BBCNewsViewModelTest.kt:30)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.RunBefores.invokeMethod(RunBefores.java:33)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:61)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
at org.gradle.api.interna
在我的 BBCNewsViewModelTest.kt 下方出現例外
@ExperimentalCoroutinesApi
class BBCNewsViewModelTest{
private var progressObserver = MutableLiveData(false)
private lateinit var apiInterface : NewsInterface
private lateinit var newsRepository: NewsRepository
private lateinit var bbcNewsResponseUseCase: BBCNewsResponseUseCase
private lateinit var viewModel: BBCNewsViewModel
@ExperimentalCoroutinesApi
@get:Rule
var mainCoroutineRule = MainCoroutineRule()
@Before
fun setUp() {
newsRepository = NewsRepository(apiInterface)
bbcNewsResponseUseCase = BBCNewsResponseUseCase(newsRepository)
viewModel = BBCNewsViewModel(bbcNewsResponseUseCase)
}
@Test
fun testsSaveSessionData() = runBlockingTest {
assert(progressObserver.value == viewModel.progress.value)
}
}
在我呼叫的介面類下方獲取新聞功能
interface NewsInterface {
@GET(Constants.BBC_URL)
suspend fun getNews(): NewsResponse
}
下面 BBCNewsViewModel.kt
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.yodgorbek.newstask.model.NewsResponse
import com.yodgorbek.newstask.domain.use_case.BBCNewsResponseUseCase
import com.yodgorbek.newstask.domain.utils.fold
import com.yodgorbek.newstask.domain.utils.parseDate
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.Comparator
@RequiresApi(Build.VERSION_CODES.N)
class BBCNewsViewModel(private val useCase: BBCNewsResponseUseCase) : ViewModel() {
var news= MutableLiveData<NewsResponse>()
// Expose to the outside world
// Expose to the outside world
private val error = MutableLiveData<String>()
var progress = MutableLiveData(false)
init{
getNews()
}
@RequiresApi(Build.VERSION_CODES.N)
private fun getNews() {
progress.postValue(true)
viewModelScope.launch(Dispatchers.IO) {
useCase.invoke()
.fold({ newsResponse ->
newsResponse.articles.sortedWith(Comparator.comparing{
it.publishedAt.parseDate()
})
news.postValue(newsResponse)
}, {
error.postValue(it.message)
})
progress.postValue(false)
}
}
}
在我的 NewsRepository.kt 下面
class NewsRepository(
private val apiInterface:NewsInterface
){
@RequiresApi(Build.VERSION_CODES.N)
suspend fun getNews() : Result<NewsResponse>{
return try {
val response = apiInterface.getNews()
Result.Success(response)
} catch (ex: Exception) {
Result.Error(ex)
}
}
}
在我的 NewsResponse.kt 下面
data class NewsResponse(
@SerializedName("articles")
val articles: List<Article>,
@SerializedName("status")
val status: String,
@SerializedName("totalResults")
val totalResults: Int
)
我想知道我到底在哪里犯錯
uj5u.com熱心網友回復:
根據例外情況,您沒有初始化apiInterface.
在正常情況下Retrofit負責創建 NewsInterface. 但在測驗的情況下,您將負責傳遞實體。為此,您可以創建模擬實作。
class MockNewsInterface: NewsInterface{
suspend fun getNews(): NewsResponse{
return NewsResponse() // Pass dummy implementation
}
}
只需在您的代碼中替換它
newsRepository = NewsRepository(MockNewsInterface())
我建議使用 Mockito 或Mockk.io庫。這將有助于輕松有效地撰寫測驗用例。
uj5u.com熱心網友回復:
正如你的例外所說lateinit property apiInterface has not been initialized
apiInterfacein未BBCNewsViewModelTest初始化
在您的setUp()方法中,您正在初始化newsRepository = NewsRepository(apiInterface),而apiInterface尚未初始化
您可以apiInterface在沒有lateinit的情況下進行宣告,或者在setup()或者如果您使用任何依賴注入,您可以進行欄位注入
由于您正在使用改造,這就是您必須初始化的方式
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
NewsInterface service = retrofit.create(NewsInterface.class);
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/430881.html
上一篇:為沒有回傳值的函式撰寫單元測驗
