Android 协同路由:覆盖OKHttp';使调度程序使用异步任务';s ThreadPoolExecutor,以便Espresso可以成功断言
我正在迁移一个应用程序,该应用程序使用Android 协同路由:覆盖OKHttp';使调度程序使用异步任务';s ThreadPoolExecutor,以便Espresso可以成功断言,android,retrofit2,android-espresso,okhttp3,kotlin-coroutines,Android,Retrofit2,Android Espresso,Okhttp3,Kotlin Coroutines,我正在迁移一个应用程序,该应用程序使用改装与协同程序一起工作。该应用程序有一些UAT失败,因为Espresso没有等待协同程序完成并立即断言 默认情况下,coroutinecaladapterfactory使用OkHttp的Dispatcher执行异步请求,但Espresso仅监视UIThread和AsyncTaks线程池。我想到的一个解决方案是强制OkHttp的调度器使用AsyncTask的ThreadPoolExecutor val dispatcher = Dispatcher(Async
改装
与协同程序一起工作。该应用程序有一些UAT失败,因为Espresso没有等待协同程序完成并立即断言
默认情况下,coroutinecaladapterfactory
使用OkHttp的Dispatcher
执行异步请求,但Espresso
仅监视UIThread
和AsyncTaks
线程池。我想到的一个解决方案是强制OkHttp
的调度器使用AsyncTask
的ThreadPoolExecutor
val dispatcher = Dispatcher(AsyncTask.THREAD_POOL_EXECUTOR as ExecutorService)
okHttpClientBuilder.dispatcher(dispatcher)
这似乎有效,测试通过了
这是个坏主意吗?注册
IdlingResource
还是一个更好的选择吗?如果没有更多关于您的设置的详细信息,我不确定这些信息是否有帮助,但我会提到一些可能对您的测试有帮助的提示:
转换遗嘱执行人
您也可以使用另一种方法,从任何执行器创建协同路由调度程序,方法是:
AsyncTask.THREAD_POOL_EXECUTOR.asCoroutineDispatcher()
当然,这可以在任何地方使用,比如Dispatchers.Main
,这意味着您可以从这个范围创建一个范围,并从这个范围启动您的协同程序,而Espresso应该监控底层执行器池的完成情况。例如:
...
val espressoScope = CoroutineScope(AsyncTask.THREAD_POOL_EXECUTOR.asCoroutineDispatcher())
...
espressoScope.launch { api.getBooks() }
类似地,您可以执行以下操作:
val asyncTaskContext = AsyncTask.THREAD_POOL_EXECUTOR.asCoroutineDispatcher()
withContext(asyncTaskContext) {
api.getBooks()
}
// OR:
@Test
fun someAndroidTest() = runBlocking(asyncTaskContext) {
// espresso logic
}
加入工作(推荐)
最后但并非最不重要的一点是,您可以加入在测试中创建的任何作业,测试将等待作业完成后再退出。这听起来像是在您的情况下最有帮助的方法,因为您真的只想等到协同程序完成:
@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()
}
那么可以使用AsyncTask线程池吗?我知道协程调度程序针对手头的任务进行了优化(即Dispatcher.IO针对IO任务进行了优化),但我不知道AsyncTask的线程池是否也进行了优化。我认为Google不推荐使用
AsyncTask
api?