Вставить поля в ViewModel в тестах - PullRequest
0 голосов
/ 03 января 2019

Как внедрить в 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>>)
    }
}

1 Ответ

0 голосов
/ 04 января 2019

Потому что:

  1. lateinit var getAll: GetNotesMainViewModel) - это переменная (не метод).
  2. любой другой человек, находящийся за пределами MainViewModel, может получить доступ к этой переменной lateinit var getAll: GetNotes.
  3. эта переменная изменчива.
  4. 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.

...