在协程中阻止了Android Instrumentation

问题描述 投票:3回答:1

我的Activity有一个EditText和一个Button。按下按钮时,将调用长时间运行的功能。在此期间,应禁用EditText。函数完成后,应重新启用EditText。这在运行应用程序时工作正常但是我已经编写了一个Espresso单元测试来测试这种似乎行为不正常的行为。

似乎长时间运行功能暂停单元测试,运行时间超过3秒。一旦长时间运行的功能完成,单元测试然后测试EditText是否被禁用,它不再是任务已完成并且loading变量被设置回false

我希望单元测试然后启动该函数,因为它在一个协程中运行,它将继续到下一行来检查EditText是否被禁用。

我尝试过CommonPool,UI,launch,async,Deferred等所有不同的变体,但似乎没有任何东西可以获得正确的行为。

suspend fun getData(): String {
    // simulate network request delay
    delay(3000)                       
    return "Hello, world!"
}

fun onButtonClicked() {
    // data binding field to disable EditText
    loading = true 

    launch(CommonPool) {
        // make "network call"
        val data = getData().await()

        // reenable EditText
        loading = false
    }
}

@Test
fun disableEditText() {
    // check the EditText starts off enabled
    onView(withId(R.id.edit_text))
            .check(matches(isEnabled()))

    // click the Button to simulate the network call
    onView(withId(R.id.button))
            .perform(click())

    // check the EditText is disabled
    onView(withId(R.id.edit_text))
            .check(matches(not(isEnabled()))
}
android kotlin coroutine android-espresso
1个回答
0
投票

一般来说,你不应该处理视图中的任何逻辑(活动,片段等),它应该在一个单独的逻辑处理程序(如ViewModel,Presenter或..)中完成。

您可以使用框架(如Mockito或MockK)来spy您的活动,并模拟getData()方法以始终快速返回,这样您的测试用例不需要等待它。

要使用mockito监视您的活动,您可以使用this回答中的信息,并使用when(activity.getData()).thenReturn("")来模拟该方法。既然你在嘲笑一个协程,你需要使用runBlocking来运行你的测试。

class MainActivityTest {
    internal var subject: MainActivity

    val activityFactory: SingleActivityFactory<MainActivity> =
        object : SingleActivityFactory<MainActivity>(MainActivity::class.java) {
            protected fun create(intent: Intent): MainActivity {
                subject = spy(getActivityClassToIntercept())
                return subject
            }
        }

    @Rule
    var testRule: ActivityTestRule<MainActivity> = ActivityTestRule(activityFactory, true, true)

    @Test
    fun sampleTest() = runBlocking<Unit> {
        `when`(subject.getData()).thenReturn("")
        //verify(subject).
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.