android - 将 ViewModelProvider.Factory 的提供者注入(inject) esspresso 测试

标签 android kotlin dagger-2 android-espresso android-viewmodel

我有 ViewModel.Factory 的自定义实现由 Dagger2 注入(inject)的 lambda 提供

interface ViewModelFactoryComponent {
    val factoryProvider: (Bundle?) -> ViewModelProvider.Factory
}

Dagger 实现如下所示:
@Module
class ViewModelModule {
    @Provides
    @Singleton
    fun bindViewModelFactory(creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<(Bundle?) -> ViewModel>>): (Bundle?) -> ViewModelProvider.Factory {
        return { ViewModelFactory(creators, it) }
    }
}

@Singleton
@Component(modules = [ ApplicationModule::class, ViewModelModule::class])
interface ApplicationComponent : ViewModelFactoryComponent

在应用程序中,一切都像魅力一样工作,但是当我尝试配置 Espresso 时出现了问题测试。这是 Dagger 测试组件配置:
@Singleton
@Component(modules = [ApplicationModule::class, ViewModelModule::class])
interface TestComponent : ApplicationComponent

现在有什么问题 - 像这样由 Dagger 生成函数生成的测试组件实现
 @Override
  public Function1<Bundle, ViewModelProvider$Factory> getFactoryProvider() {
    return bindViewModelFactoryProvider.get();
  }

这会产生编译错误,而不是像在真正的应用程序中一样:
  @Override
  public Function1<Bundle, ViewModelProvider.Factory> getFactoryProvider() {
    return bindViewModelFactoryProvider.get();
  }

一开始我以为是ViewModelProvider.Factory的情况可见性,但所有 build.gradle修改没有帮助。我遇到了完全缺乏想法的情况,所以我会很高兴至少有一些建议。

更新
我创建了一个空项目来重现这个错误,并且它应该是完全可重复的。

文件在 main目录:

@Singleton
@Component(modules = [ViewModelModule::class])
interface ApplicationComponent : ViewModelFactoryComponent

@Module
class ViewModelModule {

    @Provides
    @Singleton
    fun bindViewModelFactory(): () -> ViewModelProvider.Factory {
        return { ViewModelFactory() }
    }
}

interface ViewModelFactoryComponent {
    val factoryProvider: () -> ViewModelProvider.Factory
}

class ViewModelFactory @Inject constructor() : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return modelClass.newInstance()
    }
}

class MainActivity : AppCompatActivity()

文件在 androidTest目录:
@Singleton
@Component(modules = [ViewModelModule::class])
interface TestComponent : ApplicationComponent

@RunWith(AndroidJUnit4::class)
class TestCase {
    @get:Rule
    val activityTestRule = ActivityTestRule(MainActivity::class.java, false, false)

    @Test
    fun appLaunchesSuccessfully() {
        ActivityScenario.launch(MainActivity::class.java)
    }
}

这都是依赖项:
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'com.google.dagger:dagger:2.21'
    kapt 'com.google.dagger:dagger-compiler:2.21'
    kaptAndroidTest 'com.google.dagger:dagger-compiler:2.21'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test:rules:1.1.1'

应用程序构建没有任何问题,但是当我尝试启动 appLaunchesSuccessfully()测试,从上面的原因编译错误,出现。

编辑
所以,我发现没有 kaptAndroidTest 'com.google.dagger:dagger-compiler:2.21'测试项目可以成功构建。
坏消息是没有它 Dagger 组件类将不会生成。

最佳答案

认为你需要这个插件:

apply plugin: 'kotlin-kapt'

与这些 dependencies :
kapt "com.google.dagger:dagger-compiler:2.21"
implementation "com.google.dagger:dagger:2.21"

并启用选项 generateStubs :
kapt {
    generateStubs = true
}

有很多similar questions ...另见 user's guide .
kaptAndroidTest可能没用。

关于android - 将 ViewModelProvider.Factory 的提供者注入(inject) esspresso 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55380056/

相关文章:

android - Dagger2 如何执行具有默认构造函数依赖性的构造函数注入(inject)

android - 如果没有 @Inject 构造函数或来自 @Provides- 或 @Produces- 注释的方法,则不能提供改造

javascript - 为什么 Cordova 项目具有相同的 index.js 副本?

android - 无法在 Actionbar 中实现后退按钮

android - 如何从Google API请求适配器中的持有人中设置图标网址

android-studio - 无法为Android Studio 3.0安装Gradle

java - 为什么我不能将第一个 header 添加到 getPreferenceScreen?

java - Picasso 的永久缩略图

android - Android上的AWS Cognito SDK,参数cognitoDevice Null导致登录崩溃

java - 在 Android 上使用 Dagger2 进行依赖注入(inject)