首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >协程:重写OKHttp的dispatcher以使用AsyncTasks的ThreadPoolExecutor,以便Espresso可以成功断言

协程:重写OKHttp的dispatcher以使用AsyncTasks的ThreadPoolExecutor,以便Espresso可以成功断言
EN

Stack Overflow用户
提问于 2019-05-28 08:04:23
回答 1查看 1.1K关注 0票数 4

我正在迁移一个使用Retrofit来使用协程的应用程序。该应用程序有一些UAT正在失败,因为Espresso没有等待协程完成并立即断言。

默认情况下,CoroutineCallAdapterFactory使用OkHttp的Dispatcher来执行异步请求,但Espresso只监控UI ThreadAsyncTaksThread池。我想到的一个解决方案是强制OkHttp的Dispatcher使用AsyncTaskThreadPoolExecutor

代码语言:javascript
运行
复制
val dispatcher = Dispatcher(AsyncTask.THREAD_POOL_EXECUTOR as ExecutorService)
okHttpClientBuilder.dispatcher(dispatcher)

这似乎起作用了,并且测试通过了。

这是个坏主意吗?注册IdlingResource仍然是更好的选择吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-30 11:26:39

如果没有更多关于设置的详细信息,我不确定这些信息是否会有帮助,但我会提到一些提示,它们可能会对您的测试有所帮助:

转换执行器

您也可以采用另一种方式,使用以下命令从任何执行器创建协程调度程序:

代码语言:javascript
运行
复制
AsyncTask.THREAD_POOL_EXECUTOR.asCoroutineDispatcher()

当然,这可以用在任何你有类似Dispatchers.Main的地方,这意味着你可以创建一个作用域,并从这个作用域启动你的协程,并且Espresso应该监控底层执行器池的完成。例如:

代码语言:javascript
运行
复制
...
val espressoScope = CoroutineScope(AsyncTask.THREAD_POOL_EXECUTOR.asCoroutineDispatcher())
...
espressoScope.launch { api.getBooks() }

类似地,您可以执行以下操作:

代码语言:javascript
运行
复制
val asyncTaskContext = AsyncTask.THREAD_POOL_EXECUTOR.asCoroutineDispatcher()
withContext(asyncTaskContext) {
    api.getBooks()
}

// OR:

@Test
fun someAndroidTest() = runBlocking(asyncTaskContext) {
    // espresso logic
}

加入作业(推荐)

最后但并非最不重要的一点是,您可以加入在测试中创建的任何作业,测试将等到作业完成后才会退出。这听起来像是在你的情况下最有帮助的方法,因为你真的只想等待协程完成:

代码语言:javascript
运行
复制
@Test
fun `first book has a title`() = runBlocking {
    launch {
        // run a function that suspends and takes a while
        val firstBook = api.getAllBooks().first()
        assertNotNull(firstBook.title)
    }.join()
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56333608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档