Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hilt Fragments must be attached to an @AndroidEntryPoint Activity. Found: class androidx.fragment.app.testing.FragmentScenario$EmptyFragmentActivity

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?

like image 294
Cyrus Avatar asked Jul 31 '20 10:07

Cyrus


People also ask

Why can't I use fragmentscenario with hilt?

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.

Should I retain a hilt 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.

How to test fragment instrumented test in Android?

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.

Is it possible to use launchfragmentincontainer with hilt?

// 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.


3 Answers

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.

like image 142
Ramon Rabello Avatar answered Oct 19 '22 02:10

Ramon Rabello


For your testing purpose if you want to test fragment instrumented test you can do the following step:

  1. 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.

  2. 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.

like image 6
Rachman Abda'u Avatar answered Oct 19 '22 02:10

Rachman Abda'u


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

like image 1
Andrew Chelix Avatar answered Oct 19 '22 02:10

Andrew Chelix