Android 使用 Hilt 和 Work Manager 的仪器测试结果 java.lang.NoSuchMethodException
Android instrumentation test using Hilt and Work Manager results in java.lang.NoSuchMethodException
我想编写一个仪器测试来测试自定义工作器。我的应用程序使用 Hilt 进行依赖项注入。我的自定义 worker 需要辅助注入,因为它在构造函数中有一个附加参数。当 运行 仪器测试时,客户工作人员不会因异常而被实例化。
详情
- 工作管理器版本:2.5.0
- AndroidManifest 禁用 default Work Manager 初始化。
- 完整的错误日志 here。
错误
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。
我想编写一个仪器测试来测试自定义工作器。我的应用程序使用 Hilt 进行依赖项注入。我的自定义 worker 需要辅助注入,因为它在构造函数中有一个附加参数。当 运行 仪器测试时,客户工作人员不会因异常而被实例化。
详情
- 工作管理器版本:2.5.0
- AndroidManifest 禁用 default Work Manager 初始化。
- 完整的错误日志 here。
错误
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。