I would like to write an instrumentation test to test a custom worker. My application uses Hilt for dependency injection. My custom worker requires assisted injection as it has an additional parameter in the constructor. When running the instrumentation test the customer worker does not get instantiated as a result of an exception.
Details
- Work Manager version: 2.5.0
- AndroidManifest disables the default Work Manager initialisation.
- Full error logs here.
The Error
E/WM-WorkerFactory: Could not instantiate com.poliziano.notanotherpomodoroapp.core.storage.PreferenceSyncWorker
java.lang.NoSuchMethodException: <init> [class android.content.Context, class androidx.work.WorkerParameters]
See the full error logs here.
The Worker
@HiltWorker
class PreferenceSyncWorker @AssistedInject constructor(
@Assisted context: Context,
@Assisted appParameters: WorkerParameters,
// additional dependency to be injected
private val restApi: RestApi
) : Worker(context, appParameters) {
override fun doWork(): Result {
return Result.success()
}
}
The Test
// A custom runner to set up the instrumented application class for tests.
class CustomTestRunner : AndroidJUnitRunner() {
override fun newApplication(cl: ClassLoader?, name: String?, context: Context?): Application {
return super.newApplication(cl, HiltTestApplication::class.java.name, context)
}
}
@HiltAndroidTest
@RunWith(AndroidJUnit4::class)
class BasicInstrumentationTest {
@get:Rule(order = 0)
val hiltRule = HiltAndroidRule(this)
@Before
fun setup() {
val context = ApplicationProvider.getApplicationContext<Context>()
val config = Configuration.Builder()
.setMinimumLoggingLevel(Log.DEBUG)
.setExecutor(SynchronousExecutor())
.build()
// Initialize WorkManager for instrumentation tests.
WorkManagerTestInitHelper.initializeTestWorkManager(context, config)
}
@Test
fun shouldSyncPreference() {
// Create request
val request = OneTimeWorkRequestBuilder<PreferenceSyncWorker>()
.build()
val workManager = WorkManager.getInstance(ApplicationProvider.getApplicationContext())
// Enqueue and wait for result. This also runs the Worker synchronously
// because we are using a SynchronousExecutor.
workManager.enqueue(request).result.get()
// Get WorkInfo and outputData
val workInfo = workManager.getWorkInfoById(request.id).get()
// Assert
assertThat(workInfo.state).isEqualTo(WorkInfo.State.SUCCEEDED)
}
}