如果我编写测试,如何注入到 ViewModel 中。我收到错误UninitializedPropertyAccessException: lateinit property getAll has not been initialized
。我想测试从远程API提取数据。我是编写单元测试的新手,所以在这种情况下,我想了解如何编写。
class MainViewModel @Inject constructor(
private val commandProcessor: CommandProcessor,
private val app: Application
) : AndroidViewModel(app), CoroutineScope {
var job: Job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.IO + job
private var notesList: LiveData<List<Note>>? = null
private var editedNote: LiveData<Note>? = null
@Inject lateinit var getAll: GetNotes
@Inject lateinit var add: AddNote
private fun fetchNotes() {
getAll.execute()
notesList = getAll.result
}
fun getNotes(): LiveData<List<Note>>? {
if (notesList == null) fetchNotes()
return notesList
}
override fun onCleared() {
super.onCleared()
job.cancel()
val commands = arrayListOf(getAll, add, delete, getSingle, edit)
commands.forEach { it.cancelJob() }
}
}
测试样本:
@RunWith(MockitoJUnitRunner::class)
class MainViewModelTest {
private lateinit var viewModel: MainViewModel
val app: Application = mock()
@Inject lateinit var getAllMock: GetNotes
@Before
fun setUp() {
viewModel = MainViewModel(CommandProcessor(), app)
Mockito.`when`(viewModel.getAll).thenReturn(getAllMock)
}
@Test
fun testGetNotes() {
val livedata = MutableLiveData<List<Note>>()
Mockito.`when`(getAllMock.result).thenReturn(livedata)
assert(viewModel.getNotes() is LiveData<List<Note>>)
}
}
答案 0 :(得分:1)
因为:
lateinit var getAll: GetNotes
(在MainViewModel
中)是一个变量(不是方法)。MainViewModel
以外的任何人都可以访问此变量lateinit var getAll: GetNotes
。MainViewModel
方法中的setUp()
实例不是Mockito.mock(MainViewModel::class.java)
的真实模拟实例然后:要测试MainViewModel
中的逻辑,我们可以创建MainViewModel
实例,并简单地在setUp()
方法中设置该变量。
private lateinit var mockGetAll: GetNotes
@Before
fun setUp() {
mockGetAll = mock(GetNotes::class.java)
viewModel = MainViewModel(CommandProcessor(), app).apply {
getAll = mockGetAll
}
}
此后,我们可以模拟mockGetAll: GetNotes
的任何行为。