如何与Android WorkManager同步运行CoroutineWorker ?



我使用WorkManager在我的应用程序链多个CoroutineWorkers在一起。我正在尝试测试我的应用程序,并让这些工人同步运行,然后继续测试的其余部分。

由于CoroutineWorker是一个挂起函数,它不使用提供给工作管理器ConfigurationSynchronousExecutor()。Android文档提到CoroutineContext可以用来定制CoroutineWorker运行的线程。

我如何提供一个CoroutineContext,并有工作与测试代码同步运行?

@Test
fun LaunchLongRunningCoroutineworkersWithWorkManager_FailsDueToAsynchronosity() {
hiltRule.inject()
context = InstrumentationRegistry.getInstrumentation().targetContext
val config = Configuration.Builder()
.setWorkerFactory(delegatingWorkerFactory)
.setExecutor(SynchronousExecutor())
.build()
WorkManagerTestInitHelper.initializeTestWorkManager(context, config)
val workRequest1 = OneTimeWorkRequestBuilder<LongRunningCoroutineWorker1>()
.build()
val workRequest2 = OneTimeWorkRequestBuilder<LongRunningCoroutineWorker2>()
.build()
val workManager = WorkManager.getInstance(context)
workManager.beginUniqueWork("WORKNAME",ExistingWorkPolicy.REPLACE, workRequest1)
.then(workRequest2)
.enqueue()
val workInfo1 = workManager.getWorkInfoById(workRequest1.id).get()
val workInfo2 = workManager.getWorkInfoById(workRequest1.id).get()
/*fails expected: State.SUCCEEDED was: State.RUNNING*/
assertThat(workInfo1.state).isEqualTo(WorkInfo.State.SUCCEEDED) 
assertThat(workInfo2.state).isEqualTo(WorkInfo.State.SUCCEEDED)
}
class LongRunningCoroutineWorker1(
val context: Context,
val parameters: WorkerParameters,
) : CoroutineWorker(context, parameters) {
override suspend fun doWork(): Result {
return withContext(Dispatchers.IO) {
/*simulate long work*/
delay(5000)
Result.success()
}
}
}

不要将TestInitHelperCoroutineWorkers(或RxWorker)一起使用。这个helper函数是为Worker类构建的。

WorkManager v2.1引入了一组新的api,以支持一种更简单的方法来测试ListenableWorker类,从而支持CoroutineWorker。在我们的代码中,我们将使用这些新API之一:TestListenableWorkerBuilder。

在WorkManager的测试指南中可以获得额外的信息,并且在协程代码实验室中可以获得一个示例,它也涵盖了WorkManager。

在你的例子中,你应该有这样的内容:

@Test
fun LaunchLongRunningCoroutineworkersWithWorkManager_FailsDueToAsynchronosity() {
hiltRule.inject()
context = InstrumentationRegistry.getInstrumentation().targetContext
val worker1 = TestListenableWorkerBuilder<LongRunningCoroutineWorker1>(context)
.setWorkerFactory(delegatingWorkerFactory)
.build()
// "Manually" start the work
val result1 = worker1.startWork().get()
assertThat(result).isEqualTo(Result.success())
val worker2 = TestListenableWorkerBuilder<LongRunningCoroutineWorker2>(context)
.setWorkerFactory(delegatingWorkerFactory)
.build()
// "Manually" start the work
val result2 = worker1.startWork().get()
assertThat(result).isEqualTo(Result.success())
}

最新更新