首页 > 解决方案 > 为 WorkManager 测试 RxWorker

问题描述

我想第一次尝试工作经理。我习惯了 rxJava,所以我决定使用 RxWorker 来实现我的工作管理器。但是测试方面让我很头疼。基本上,工作经理检查firebase以获取对特定文档的最新更改的最新更改(这不是我所知道的最佳用例)。但问题在于测试返回而不等待成功或失败。它在工作管理器仍在运行时返回。

这是我的工作经理实现

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 返回成功或失败。但它在工作管理器仍在运行时返回

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

标签: androidrx-java2android-workmanager

解决方案


WorkManager 提供了几种测试Worker类的方法。您可以在WorkManager 测试文档页面上找到所有详细信息。

原来WorkManagerTestInitHelper只支持Worker类,同时(WorkManager v2.1.0-alpha01)中新引入的TestListenableWorkerBuilder可以用来测试这两个ListenableWorker类以及从它派生的其他类(如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()))
    }
}

这样,您就可以同步调用您的工人阶级。

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

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

您可以在Kotlin 的协程 Codelab上找到类似的完整示例(用于 a CoroutineWorker)。


推荐阅读