Android 使用 Hilt 和 Work Manager 的仪器测试结果 java.lang.NoSuchMethodException

Android instrumentation test using Hilt and Work Manager results in java.lang.NoSuchMethodException

我想编写一个仪器测试来测试自定义工作器。我的应用程序使用 Hilt 进行依赖项注入。我的自定义 worker 需要辅助注入,因为它在构造函数中有一个附加参数。当 运行 仪器测试时,客户工作人员不会因异常而被实例化。

详情

错误

E/WM-WorkerFactory: Could not instantiate com.poliziano.notanotherpomodoroapp.core.storage.PreferenceSyncWorker
    java.lang.NoSuchMethodException: <init> [class android.content.Context, class androidx.work.WorkerParameters]

查看完整的错误日志 here

工人

@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()
    }
}

测试

// 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)
    }
}

一个常见问题是 WorkManager 未在 AndroidManifest 中被禁用。就我而言,这是一个缺失的依赖项:kapt "androidx.hilt:hilt-compiler:1.0.0".

有两个 Hilt 编译器依赖项:

  • kapt "com.google.dagger:hilt-compiler:2.5.0" 用于核心 Hilt 库。
  • kapt "androidx.hilt:hilt-compiler:1.0.0" 这是 Jetpack 架构库所必需的 - 例如 WorkManager。