[英]Testing livedata with Robolectric
我有以下測試來檢查活動是否通過視圖模型從存儲庫正確獲取數據。
@Config(application = TestApplication::class)
@RunWith(RobolectricTestRunner::class)
@LooperMode(LooperMode.Mode.PAUSED)
class BusinessTests {
private lateinit var viewModel: BusinessCollectionViewModel
private lateinit var activity: BusinessCollectionVerticalActivity
private lateinit var observer: Observer<Triple<NetworkState, PagedList<Edge<Business>>, TimeTracking?>>
@Before
fun setUp() {
observer = mock()
}
@Test
fun givenBusinessMock_whenVerticalCollection_thenBusinessVerticalWith2Items() {
val activityScenario = ActivityScenario.launch(BusinessCollectionVerticalActivity::class.java)
activityScenario.onActivity {
activity = it
}
viewModel = ViewModelProviders.of(activity)[BusinessCollectionViewModel::class.java]
viewModel.data.observeForever(observer)
assert(viewModel.data.value?.second?.size == 2)
}
}
問題是測試總是失敗,但在調試中它正確通過,但是當我在斷言中使用錯誤條件調試它時,會彈出以下異常。
java.lang.Exception: Main looper has queued unexecuted runnables. This might be the cause of the test failure. You might need a shadowOf(getMainLooper()).idle() call.
這真是奇怪的行為,我不知道該怎么辦。 當然,我嘗試在觀察之前添加 shadowOf(getMainLooper()).idle() 。
我正在使用最新的 robolectric 4.3,這可能是一個錯誤嗎?
問題在於,當assert
在不同的線程中運行時,運行 UI 測試的線程正在完成而沒有任何錯誤。
您可以更改測試方法以保持線程,直到它被運行 observeOnce 的線程釋放:
@Test
fun givenBusinessMock_whenVerticalCollection_thenBusinessVerticalWith2Items() {
val syncObject = Object()
val activityScenario = ActivityScenario.launch(BusinessCollectionVerticalActivity::class.java)
activityScenario.onActivity {
activity = it
}
viewModel = ViewModelProviders.of(activity)[BusinessCollectionViewModel::class.java]
viewModel.data.observeOnce {
assert(it.second.size == 2)
synchronized (syncObject) {
syncObject.notify()
}
}
synchronized (syncObject) {
syncObject.wait()
}
}
如果你想要一個更好的方法,你可以在你的數據中觀察 Forever 並檢查值:
var observer: Observer<?> // replace ? by your type
viewModel.data.observeForever(observer)
assert(viewModel.data.value.second.size == 2)
這篇文章中有更多信息。
我和你有同樣的問題,我通過使用instantTaskExecutorRule修復了它。
您需要在您的 app buil.gradle 文件中添加以下依賴項:
testImplementation 'androidx.arch.core:core-testing:2.1.0'
並在您的測試中包含以下規則:
// Executes tasks in the Architecture Components in the same thread
@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.