簡體   English   中英

使用 Robolectric 測試實時數據

[英]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.

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