I am trying to write Android instrumentation tests for a class that contains WorkManager WorkRequests.
For a long time I was stuck at the point where I could see the workers being enqueued but they never got executed. After some time and trial and error I realised the following constraint was blocking the test:
...
setConstraints(Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build())
...
If I remove that constraint the work item is executed as expected.
My virtual device has a network connection so not sure why this constraint isn't being met in my test.
Does anyone have any advice on how to fix this as I need to write tests that cover cases where this constraint is met and when it isn't.
My work request is pretty simple but here it is:
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)
I have tried:
val wifi = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
wifi.isWifiEnabled = true
but this throws a Security exception:
SecurityException: WifiService: Neither user 10139 nor current process has android.permission.CHANGE_WIFI_STATE.
I have also added code to my test to check network state:
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetwork: NetworkInfo? = cm.activeNetworkInfo
val isConnected: Boolean = activeNetwork?.isConnected == true
And isConnected is true but still the WorkManager constraint is not met and so the work is not executed.
Also tried:
val testDriver = getTestDriver()
with
testDriver?.setAllConstraintsMet(workInfo.id)
inside my observe LiveData by tag method which I can see being executed once for the ENQUEUED state.
Here is my observer in the test:
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()
}
}
})
Thanks, Paul