如何使用 setRequiredNetworkType(NetworkType.CONNECTED) 约束测试 Android WorkManager?

Pau*_*aul 6 android android-testing android-instrumentation android-workmanager

我正在尝试为包含 WorkManager WorkRequests 的类编写 Android 检测测试。

很长一段时间,我都被困在我可以看到工人排队但他们从未被处决的地步。经过一段时间的反复试验,我意识到以下约束阻止了测试:

...
 setConstraints(Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build())
...
Run Code Online (Sandbox Code Playgroud)

如果我删除该约束,工作项将按预期执行。

我的虚拟设备有网络连接,所以不确定为什么我的测试没有满足这个限制。

有没有人对如何解决这个问题有任何建议,因为我需要编写测试来涵盖满足和不满足此约束的情况。

我的工作要求非常简单,但它是:

val workRequest = OneTimeWorkRequestBuilder<T>()
                .addTag(syncWork.getSyncType().name)
                .setConstraints(Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build())
                .build()

syncWorkRepository.save(syncWork.apply { id = workRequest.id.toString() })

workManager.enqueue(workRequest)
Run Code Online (Sandbox Code Playgroud)

我试过了:

val wifi = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
    wifi.isWifiEnabled = true
Run Code Online (Sandbox Code Playgroud)

但这会引发安全异常:

SecurityException: WifiService: Neither user 10139 nor current process has android.permission.CHANGE_WIFI_STATE.
Run Code Online (Sandbox Code Playgroud)

我还在测试中添加了代码来检查网络状态:

val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val activeNetwork: NetworkInfo? = cm.activeNetworkInfo
    val isConnected: Boolean = activeNetwork?.isConnected == true
Run Code Online (Sandbox Code Playgroud)

并且 isConnected 为真但仍然不满足 WorkManager 约束,因此不执行工作。

还试过:

val testDriver = getTestDriver()
Run Code Online (Sandbox Code Playgroud)

testDriver?.setAllConstraintsMet(workInfo.id)
Run Code Online (Sandbox Code Playgroud)

在我通过标记方法观察 LiveData 中,我可以看到它为 ENQUEUED 状态执行了一次。

这是我在测试中的观察者:

syncManager.syncWork(SyncType.ALL)
        .observe(lifecycleOwner, Observer { listOfWorkInfo ->
        listOfWorkInfo.forEach { workInfo ->
            Log.d("TAG", "${workInfo.id}")
            testDriver?.setAllConstraintsMet(workInfo.id)
            if(workInfo.state == WorkInfo.State.SUCCEEDED) {
                Log.d("TAG", workInfo.state.name)
                latch.countDown()
            } else if(workInfo.state != WorkInfo.State.ENQUEUED) {
                Log.d("TAG", workInfo.state.name)
                latch.countDown()
            }
        }
    })
Run Code Online (Sandbox Code Playgroud)

谢谢,保罗

Rah*_*hul 0

你应该使用WorkManagerTestInitHelper. 一旦您使用TestDriver并将约束标记为已满足,您Worker就应该执行。