Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bound Multiple Times issue when using Hilt for UI Test, TestInstalln #3209

Closed
ankitkhare opened this issue Feb 3, 2022 · 9 comments
Closed

Comments

@ankitkhare
Copy link

ankitkhare commented Feb 3, 2022

Hello, I've created a fake urlprovider binding and annotated with @TestInstallIn

@Module
@TestInstallIn(
    components = [SingletonComponent::class],
    replaces = [UrlModuleBindings::class]
)
abstract class FakeUrlBindings {

    @Binds
    abstract fun bindsUrlProvider(urlProvider: FakeUrlProvider): UrlProvider
}

This is inside androidTest
my Prod UrlProvider looks like

@Module
@InstallIn(SingletonComponent::class)
abstract class UrlModuleBindings {

    @Binds
    abstract fun bindsUrlProvider(urlProvider: DefaultUrlProvider): UrlProvider
}

This is Original Binding
when I'm running the UI test getting the error **UrlProvider is bound multiple times:**

As per the documentation everything seems correct, can I please know what is the issue with this.

Have followed https://dagger.dev/hilt/testing.html

https://stackoverflow.com/questions/70844153/bound-multiple-times-issue-when-using-hilt-for-ui-test-testinstalln

@bcorso
Copy link

bcorso commented Feb 3, 2022

Hi @ankitkhare,

Can you provide the full error message please?

@ankitkhare
Copy link
Author

ankitkhare commented Feb 7, 2022

Hi @bcorso

This the full error message

/Users/ankit.khare/AndroidStudioProjects/MyApplication/app/build/generated/source/kapt/debugAndroidTest/com/example/myapplication/MainActivityUITest_HiltComponents.java:129: error: [Dagger/DuplicateBindings] com.example.myapplication.data.UrlProvider is bound multiple times:
  public abstract static class SingletonC implements MainActivityUITest_GeneratedInjector,
                         ^
      @org.jetbrains.annotations.NotNull @Binds com.example.myapplication.data.UrlProvider com.example.myapplication.FakeUrlBindings.getUrlProvider(com.example.myapplication.FakeUrlProvider)
      @Binds @org.jetbrains.annotations.NotNull com.example.myapplication.data.UrlProvider com.example.myapplication.di.UrlModuleBindings.getUrlProvider(com.example.myapplication.data.DefaultUrlProvider)
      com.example.myapplication.data.UrlProvider is injected at
          com.example.myapplication.di.NetworkModule.provideRetrofit(…, urlProvider, …)
      retrofit2.Retrofit is injected at
          com.example.myapplication.di.NetworkModule.provideApiService(retrofit)
      com.example.myapplication.data.network.PlaceHolderApi is injected at
          com.example.myapplication.domain.DefaultApiManager(api)
      com.example.myapplication.domain.DefaultApiManager is injected at
          com.example.myapplication.di.AppModule.provideApiHelper(apiManager)
      com.example.myapplication.domain.ApiManager is injected at
          com.example.myapplication.ui.MainViewModel(apiManager)
      com.example.myapplication.ui.MainViewModel is injected at
          com.example.myapplication.ui.MainViewModel_HiltModules.BindsModule.binds(arg0)
      @dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at
          dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap() [com.example.myapplication.MainActivityUITest_HiltComponents.SingletonC → com.example.myapplication.MainActivityUITest_HiltComponents.ActivityRetainedC → com.example.myapplication.MainActivityUITest_HiltComponents.ViewModelC]

@bcorso
Copy link

bcorso commented Feb 8, 2022

@ankitkhare thanks!

Hmm, I see some of the class names don't quite align from your initial question. Is FakeUrlBindings a separate module from FakeAppBindings or is one of those just a typo?

Otherwise, I'm not really sure why UrlModuleBindings is not replaced in your test. If it's possible to put together a sample app that reproduces the issue that would help a lot.

@ankitkhare
Copy link
Author

Hi @bcorso that was a typo I renamed it

Have tried to create a small sample

https://github.com/ankitkhare/Hilt_UItest_Demo.

Please have a look. Thanks.

@bcorso
Copy link

bcorso commented Feb 9, 2022

Thanks for the sample project @ankitkhare!

I was able to repro the issue in your project, however it may take me a few days before I can start debugging and fixing it. I'll update here once I know something.

@bcorso
Copy link

bcorso commented Feb 13, 2022

Hi @ankitkhare,

Sorry for the delay!

To fix this, you need to remove the @Module.includes from AppModule.

- @Module(includes = [UrlModuleBindings::class, NetworkModule::class])
+ @Module
@InstallIn(SingletonComponent::class)
object AppModule {
  // ...
}

The issue is that while Hilt does uninstall the explicit UrlModuleBindings module usage in the generated code, it's still transitively included by AppModule.

In Hilt, you shouldn't ever need to use @Module.includes unless you're including a non-Hilt module that you can't use @InstallIn on directly. In this case, UrlModuleBindings already has @InstallIn on it so it shouldn't be included by another module.

@ankitkhare
Copy link
Author

Thanks @bcorso. Working now.

@sarimmehdi
Copy link

For me it still doesn't work and I am not even using Includes with Module annotation anywhere

@bcorso
Copy link

bcorso commented Jan 7, 2023

@sarimmehdi you will need to file a bug with more details. If your issue isn't related to using @Module.includes then we'll need enough information to figure out what the actual issue is. Ideally, you could give us a minimal reproducible example so that we can reproduce your issue and debug.

Edit: I see you filed #3692 already. I'll take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants