Issue
I have custom implementation of ViewModel.Factory
which is provided by lambda injected by Dagger2
interface ViewModelFactoryComponent {
val factoryProvider: (Bundle?) -> ViewModelProvider.Factory
}
Dagger implementation looks like below:
@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
In application everything works like a charm but problem appeared when I've tried to configure Espresso
test. Here's dagger test component configuration:
@Singleton
@Component(modules = [ApplicationModule::class, ViewModelModule::class])
interface TestComponent : ApplicationComponent
Now what is the problem - test component implementation generated by dagger generate function like this
@Override
public Function1<Bundle, ViewModelProvider$Factory> getFactoryProvider() {
return bindViewModelFactoryProvider.get();
}
which generate compilation error, instead like in real app:
@Override
public Function1<Bundle, ViewModelProvider.Factory> getFactoryProvider() {
return bindViewModelFactoryProvider.get();
}
First I thought it's a case of ViewModelProvider.Factory
visibility, but all build.gradle
modification didn't help. I've met with total lack of idea so I will be greatfull for at least some suggestions.
UPDATE I have created empty project to reproduce this error and it suppose to be completly repeatable.
File in main
directory:
@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()
File in androidTest
directory:
@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)
}
}
And this are all dependencies:
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'
Application is build without any problem but when I try to launch appLaunchesSuccessfully()
test, compile error from reason above, appear.
Edit
So, I figured out that without kaptAndroidTest 'com.google.dagger:dagger-compiler:2.21'
test project can be build successfully.
The bad new is that without it dagger component class won't generate.
Solution
According to https://github.com/google/dagger/issues/1454 and https://youtrack.jetbrains.net/issue/KT-27936 there is only a temporary solution under first link
Answered By - Karol Kulbaka
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.