3

我的 Espresso Idling 资源不工作 - 它可以编译并运行,但不再等待足够长的时间来从网络返回结果。


  1. 从https://github.com/chiuki/espresso-samples/tree/master/idling-resource-okhttp开始
  2. 将主要活动转换为 Kotlin - 测试(仍在 java 中)仍然适用于 OKHttpIdlingResource
  3. 转换为 anko 协程调用而不是 retrofit.enqueue - 测试不再有效。

这是 MainActivity 的全部新代码

import android.app.Activity
import android.os.Bundle
import android.widget.TextView
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.async
import org.jetbrains.anko.coroutines.experimental.bg

import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory

class MainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        doCallAsync()
    }

    private fun doCallAsync() = async(UI) {

        val user = bg { getUser() }
        val name = user.await().name
        val nameView = findViewById(R.id.name) as TextView

        nameView.text = name;

    }

    private fun getUser(): User {

        val retrofit = Retrofit.Builder()
                .baseUrl("https://api.github.com/")
                .addConverterFactory(MoshiConverterFactory.create())
                .client(OkHttpProvider.getOkHttpInstance())
                .build()

        val service = retrofit.create(GitHubService::class.java)


        val response = service.getUser("chiuki").execute().body()

        return response!!

    }
}

4

2 回答 2

0

Convert to anko coroutine call instead of retrofit.enqueue - test no longer works.

retrofit.enqueue使用 OkHttp 的调度程序。这就是“idling-resource-okhttp”识别并与 idlingresource 管理器通信的内容。

但是,通过使用retrofit.execute和 anko,bg您正在使用 idlingresource 管理器不知道的不同执行机制,因此当它可能正在执行时,从管理器的角度来看,应用程序处于空闲状态,从而结束了测试。

要解决此问题,您需要为使用IdlingResource的任何执行机制注册一个bg,以便它可以识别该执行线程上何时发生了某些事情。

于 2017-08-14T21:11:45.500 回答
0

您必须创建一个IdlingResource告诉 Espresso 应用程序当前是否处于空闲状态(如 Kiskae 所写)。AFAIK for coroutines 不存在可以告诉您是否有协程正在运行的中央注册表。

因此,您必须按照文档中的建议,使用CountingIdlingResource. 将此便利async-wrapper 添加到您的项目中:

public fun <T> asyncRes(
        idlingResource: CountingIdlingResource,
        context: CoroutineContext = DefaultDispatcher,
        start: CoroutineStart = CoroutineStart.DEFAULT,
        parent: Job? = null,
        block: suspend CoroutineScope.() -> T
): Deferred<T> = async(context, start, parent) {
    try {
        idlingResource.increment()
        block()
    } finally {
        idlingResource.decrement()
    }
}

CountingIdlingResource在 Activity中添加一个实例,调用asyncRes而不是async传入CountingIdlingResource.

class MainActivity : Activity() {

    // Active coroutine counter
    val idlingResource = CountingIdlingResource("coroutines")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        doCallAsync()
    }

    private fun doCallAsync() = asyncRes(idlingResource, UI) {
        ...
    }
    ...
}
于 2018-01-14T12:44:11.907 回答