簡體   English   中英

如何使用 MockK 在 Android 中測試 Kotlin 暫停調用?

[英]How do I test a Kotlin suspend call in Android with MockK?

我正在使用 Android 應用程序嘗試 TDD。 我在 Kotlin 中編寫它,因此我轉向 MockK 進行測試,但有一件事(目前)我無法找到如何做:測試暫停調用。

我為 ViewModel 中的 LiveData 值編寫了一個測試,並使其工作。 但是,當我將協程添加到組合中時,我開始收到“Method getMainLooper not mocked”消息。

這是我的代碼:

ToDoListViewModelTest.kt

class ToDoListViewModelTest {

    @get:Rule
    var instantExecutorRule = InstantTaskExecutorRule()

    @MockK
    private lateinit var toDoListLiveDataObserver: Observer<List<ToDoItem>>

    @MockK
    private lateinit var getToDoItemsUseCase: GetToDoItemsUseCase

    @Before
    fun setUp() {
        MockKAnnotations.init(this)
        every { toDoListLiveDataObserver.onChanged(any()) } answers { nothing }
    }

    @Test
    fun toDoList_listItems_noItems() = runBlocking {

        coEvery { getToDoItemsUseCase() } coAnswers { emptyList<ToDoItem>() }

        val toDoListViewModel = ToDoListViewModel(getToDoItemsUseCase)
        toDoListViewModel.toDoItemList.observeForever(toDoListLiveDataObserver)

        toDoListViewModel.updateItemList()

        assertEquals(0, toDoListViewModel.toDoItemList.value?.size)
    }
}

ToDoListViewModel.kt

class ToDoListViewModel(private val getToDoItemsUseCase: GetToDoItemsUseCase) : ViewModel() {

    private val _toDoItemList: MutableLiveData<List<ToDoItem>> = MutableLiveData()
    val toDoItemList : LiveData<List<ToDoItem>> = _toDoItemList

    fun updateItemList() {
        viewModelScope.launch(Dispatchers.IO) {
            _toDoItemList.value = getToDoItemsUseCase()
        }
    }
}

GetToDoItemsUseCase.kt

class GetToDoItemsUseCase {
    suspend operator fun invoke(): List<ToDoItem> {
        return listOf()
    }
}

我嘗試過的事情:

  • 添加“@RunWith(BlockJUnit4ClassRunner::class)”:沒有變化
  • 在 Gradle 文件中添加“testOptions { unitTests.returnDefaultValues = true }”:Looper 錯誤消失,但來自 LiveData 的值是 null,而不是“coEvery”調用中指定的空列表。
  • 調用“Dispatchers.setMain(newSingleThreadContext("UI Thread"))”:與上例相同,從 LiveData 獲取 null。

我對測試不是很有經驗,而且我已經沒有選擇了。 我覺得我肯定需要社區的幫助;)

另外,如果由於某種原因我的設置不正確(應該使用 MockK 或其他測試框架以外的東西......),請也對此發表評論。 在這方面我還有很多東西要學。

使用 postValue _toDoItemList.postValue(getToDoItemsUseCase())

根據文檔:

設置值()

設置值。 如果有活躍的觀察者,值將被分派給他們。 必須從主線程調用此方法。

后值()

將任務發布到主線程以設置給定值。 如果您在主線程執行發布的任務之前多次調用此方法,則只會分派最后一個值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM