I'm using Android work manager with a custom initialization. to do that i disable auto-initialization in the manifest like this
<provider
tools:replace="android:authorities"
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.work_manager_init"
android:enabled="false"
android:exported="false" />
And in application code I use this code
private fun initWorkManager() {
WorkManager.initialize(this, Configuration.Builder().run {
setWorkerFactory(appComponent.daggerWorkerFactory())
build()
})
}
And it works fine when I run my application. But when I'm testing with roboletric any class that needs the context by RuntimeEnvironment.application
throws this exception
java.lang.IllegalStateException: WorkManager is already initialized.
Did you try to initialize it manually without disabling
WorkManagerInitializer? See WorkManager#initialize(Context,
Configuration) or the class levelJavadoc for more information.
The initWorkManager()
get calls and throw this beacuse it doesn't know auto-init is already disabled in the manifest and somehow my test cannot read the values from the manifest file.
Any help or suggestion will be appritiated.
You can check this by running getStatus() method on the WorkInfo instance. Calling the state immediately after enqueuing the WorkRequest will give the state as ENQUEUED and hence don't get any output data.
To test a ListenableWorker or its variants ( CoroutineWorker and RxWorker ), use TestListenableWorkerBuilder .
WorkManager is not answer to all of the background tasks. E.G. You shouldn't use it for processing payments since it doesn't need to survive process death and these task needs to be executed immediately. Consider using Foreground Service. Its also not a great idea to use them for parsing data and contents of view.
I solved a similar issue with the help of the Androidx Work Manager testing utils. For reference see the docs here: Android work manager testing docs
Basically what you need to do is add a dependency to include the work manger test utils:
testImplementation 'androidx.work:work-testing:2.0.1'
Then you will be able to call code in your test setup similar to this:
final Configuration config = new Configuration.Builder()
.setMinimumLoggingLevel(Log.DEBUG)
.setExecutor(new SynchronousExecutor())
.build();
WorkManagerTestInitHelper.initializeTestWorkManager(
context, config);
Whereas the context could obtained in different ways, depending on your test infrastructure.
With this approach no other steps like excluding something from the manifest are necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With