使用 Hilt 和 Work Manager 的 Android 检测测试导致 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)
    }
}

解决方法

一个常见问题是在 AndroidManifest 中没有禁用 WorkManager。就我而言,它缺少依赖项: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)所必需的。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...