I got following error when i run my unit test code.
Caused by: java.lang.IllegalStateException: Hilt Fragments must be attached to an @AndroidEntryPoint Activity. Found: class androidx.fragment.app.testing.FragmentScenario$EmptyFragmentActivity
at dagger.hilt.internal.Preconditions.checkState(Preconditions.java:83)
at dagger.hilt.android.internal.managers.FragmentComponentManager.createComponent(FragmentComponentManager.java:75)
at dagger.hilt.android.internal.managers.FragmentComponentManager.generatedComponent(FragmentComponentManager.java:63)
at com.zhixin.wedeep.homepage.ui.Hilt_HomePage.generatedComponent(Hilt_HomePage.java:70)
at com.zhixin.wedeep.homepage.ui.Hilt_HomePage.inject(Hilt_HomePage.java:89)
at com.zhixin.wedeep.homepage.ui.Hilt_HomePage.initializeComponentContext(Hilt_HomePage.java:53)
at com.zhixin.wedeep.homepage.ui.Hilt_HomePage.onAttach(Hilt_HomePage.java:45)
at androidx.fragment.app.Fragment.onAttach(Fragment.java:1602)
at com.zhixin.wedeep.homepage.ui.Hilt_HomePage.onAttach(Hilt_HomePage.java:35)
at com.zhixin.wedeep.homepage.ui.HomePage.onAttach(HomePage.kt:281)
This is my test code.
@HiltAndroidTest
@UninstallModules(HomePageDataModule::class)
@RunWith(AndroidJUnit4::class)
@LargeTest
class TestHomePageFragment {
private val c = Composition("cyrus", "background", "description", "downloadUrl", "1000", "url", "1", true, "100", 100, "100", "test", "title", "1", "100", "cover", ArrayList(), "ONCE", null)
@Inject
lateinit var cpd: CompositionDao
@get:Rule
var hiltRule = HiltAndroidRule(this)
@Before
fun init() {
hiltRule.inject()
Util.RETROFIT
Util.enqueueResponse("mainpage.json")
cpd.createComposition(c)
cpd.createBrowseRecord(BrowseRecord(c.id, System.currentTimeMillis()))
val s = launchFragment<HomePage>()
s.onFragment {
IdlingRegistry.getInstance().register(it.mIdleResource)
}
/* dataBindingIdlingResourceRul = DataBindingIdlingResourceRule(s)
dataBindingIdlingResourceRul.starting(null)*/
}
@Test
fun testDataInitial() {
onView(ViewMatchers.withId(R.id.recycler_view_preview_data))
.perform(RecyclerViewActions.scrollToPosition<RecyclerView.ViewHolder>(1))
}
@After
fun finish(){
}
}
Any idea for this question?
Warning: Hilt does not currently support FragmentScenario because there is no way to specify an activity class, and Hilt requires a Hilt fragment to be contained in a Hilt activity. One workaround for this is to launch a Hilt activity and then attach your fragment.
A Hilt fragment should never be retained because it holds a reference to the component (responsible for injection), and that component holds references to the previous Activity instance. In addition, scoped bindings and providers that are injected into the fragment can also cause memory leaks if a Hilt fragment is retained.
For your testing purpose if you want to test fragment instrumented test you can do the following step: Create New Activity for Activity Container in your debug source set (or if you don't have debug folder/source set just make it in your main package) you can see the code here and register the activity in Android manifest.
// UI tests here. It is not possible to use launchFragmentInContainer from the androidx.fragment:fragment-testing library with Hilt, because it relies on an activity that is not annotated with @AndroidEntryPoint. Use the launchFragmentInHiltContainer code from the architecture-samples GitHub repository instead.
As stated on Hilt guide, "Testing" section:
Warning: Hilt does not currently support FragmentScenario because there is no way to specify an activity class, and Hilt requires a Hilt fragment to be contained in a Hilt activity. One workaround for this is to launch a Hilt activity and then attach your fragment.
The error is happening since hilt-managed fragment should be attached to a hilt-managed Activity as well, in short, both should be annotated with @AndroidEntryPoint
. Because FragmentScenario uses an EmptyFragmentActivity to hold the underlying fragment being tested, currently there's no way to integrate Hilt with FragmentScenario. An workaround is to launch an activity and then attach the fragment to it.
For your testing purpose if you want to test fragment instrumented test you can do the following step:
Create New Activity for Activity Container in your debug source set (or if you don't have debug folder/source set just make it in your main package) you can see the code here and register the activity in Android manifest.
And finally create this inline function in your androidTest package.
You can just literally copy-paste code that I have mentioned. It worked well for me. Those code are provided by Manuel Vivo.
The solution lies in this Github project -> https://github.com/android/architecture-samples/blob/dev-hilt/app/src/androidTest/java/com/example/android/architecture/blueprints/todoapp/HiltExt.kt
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With