У меня есть собственная реализация ViewModel.Factory
, которая предоставляется лямбдой, введенной Dagger2
interface ViewModelFactoryComponent {
val factoryProvider: (Bundle?) -> ViewModelProvider.Factory
}
Реализация кинжала выглядит следующим образом:
@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 Test:
@Singleton
@Component(modules = [ApplicationModule::class, ViewModelModule::class])
interface TestComponent : ApplicationComponent
Теперь в чем проблема - реализация тестового компонента, сгенерированная функцией генерации кинжала, подобной этой
@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 не сгенерируется.
public Function1<Bundle, ViewModelProvider$Factory> getFactoryProvider()
не компилируется из-за '$' - person Karol Kulbaka   schedule 28.03.2019