android - 为 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>
解决方案
WorkManager 提供了几种测试Worker
类的方法。您可以在WorkManager 测试文档页面上找到所有详细信息。
原来WorkManagerTestInitHelper
只支持Worker
类,同时(WorkManager v2.1.0-alpha01)中新引入的TestListenableWorkerBuilder
可以用来测试这两个ListenableWorker
类以及从它派生的其他类(如CoroutineWorker
和RxWorker
.
在您的特定情况下,您应该能够:
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
)。
推荐阅读
- raku - 在 Raku 中实现函数对象“power”运算符
- node.js - How to display windowid of electron app window in its content on MacOS
- flutter - Flutter中如何集成支付处理平台进行点对点支付
- python-sphinx - Sphinx 中的搜索结果不显示带有搜索词的文本片段
- sympy - 我想对一个用 sympy 编写的函数进行lambdify
- python - 使用多处理模块存在活动套接字连接时,Flask 服务器无法正常工作
- html - CSS - 如何在左侧边栏的右侧放置 div 并在窗口调整大小时调整它的大小
- mysql - 如何在 Baikal/SabreDAV 上实现加密?
- javascript - 为什么我的 Javascript 过滤器只显示第一行
- latex - 投影仪子列表中的多种类型的项目符号列表