为 WorkManager 测试 RxWorker

Testing RxWorker for WorkManager

我想第一次试用工作管理器。我习惯了 rxJava,所以我决定使用 RxWorker 来实现我的工作管理器。但是测试方面给了我 headache.Basically,工作经理检查 firebase 以获取对特定文档的最新更改的最新更改(这不是我所知道的最佳用例)。但问题出在测试中 returns 无需等待成功或 failure.It returns 当工作管理器仍然是 运行.

这是我的工作管理器实现

class MidiSyncWorker(context: Context, params: WorkerParameters) : RxWorker(context, params) {
    override fun createWork(): Single<Result> {
        return Injection.provideSharePrefsRepo.midiArchiveVersion()
                .flatMapObservable { currentVersion ->
                    Injection.provideOnlineRepo.latestMidiArchive()
                            .filter { onlineMidi -> onlineMidi.version > currentVersion }
                }.firstOrError()
                .map { onlineMidi ->
                    val outputData = Data.Builder()
                            .putString(KEY_FIREBASE_ARCHIVE_PATH, onlineMidi.url)
                    Result.success(outputData.build()) }
                 }
                 .onErrorReturn { Result.failure() }

}

这是我的测试

   fun midiSyncVersionCheck_success_onlineVersionDiffersFromLocalVersion() {
       // create request
       val request = OneTimeWorkRequestBuilder<MidiSyncWorker>()
               .build()

       wmRule.workManager.enqueue(request).result.get()

       val workInfo = wmRule.workManager.getWorkInfoById(request.id).get(10, TimeUnit.SECONDS)

       assertThat(workInfo.state, `is`(WorkInfo.State.SUCCEEDED))
   }

我预计测试要等到 workmanager returns 成功或失败。但它 returns 而工作经理仍然 运行

java.lang.AssertionError:
Expected: is <SUCCEEDED>
but: was <RUNNING>

WorkManager 提供了多种方法来测试您的 Worker classes。您可以在 WorkManager Testing documentation page.

上找到所有详细信息

原始的 WorkManagerTestInitHelper only supports Worker classes, meanwhile, the newly introduce in (WorkManager v2.1.0-alpha01) TestListenableWorkerBuilder 可用于测试 ListenableWorker classes 和派生自它的其他 classes(如 CoroutineWorkerRxWorker.

在您的特定情况下,您应该能够做到:

import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.work.ListenableWorker.Result
import androidx.work.testing.TestListenableWorkerBuilder
import org.hamcrest.CoreMatchers.`is`
import org.junit.Assert.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

@RunWith(JUnit4::class)
class MyWorkTest {
    private lateinit var context: Context

    @Before
    fun setup() {
        context = ApplicationProvider.getApplicationContext()
    }

    @Test
    fun testMidiSyncWorker() {
        // Get the ListenableWorker
        val worker = TestListenableWorkerBuilder<MidiSyncWorker>(context).build()

        // Start the work synchronously
        val result = worker.startWork().get()

        assertThat(result, `is`(Result.success()))
    }
}

通过这种方式,您可以同步调用您的工作人员 class。

在这种情况下,您需要在 build.gradle 文件中使用作为测试依赖项:

def work_version = "2.1.0-alpha02"
androidTestImplementation "androidx.work:work-testing:$work_version"

您可以在 Kotlin's coroutine Codelab.

上找到类似的完整样本(对于 CoroutineWorker