简体   繁体   English

Hilt Fragment 必须附加到@AndroidEntryPoint Activity,同时测试(它附加到@AndEntPoint 标记的活动)

[英]Hilt Fragment has to be attached to @AndroidEntryPoint Activity, while testing (it is attached to @AndEntPoint marked activity)

I followed a lot of tutorials/ articles and the googles architecture sample我关注了很多教程/文章和谷歌架构示例

No matter what I try I keep getting an error saying that I need to attach Fragment to @AndroidEntryPoint annotated Activity.无论我尝试什么,我都会收到一条错误消息,提示我需要将 Fragment 附加到 @AndroidEntryPoint 带注释的 Activity。 I've setup everything correctly but still can't get this to work properly.我已经正确设置了所有内容,但仍然无法使其正常工作。

java.lang.IllegalStateException: Hilt Fragments must be attached to an @AndroidEntryPoint Activity. Found: class com.nikolam.colorme.HiltTestActivity
    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:64)
    at com.nikolam.main_feature.presenter.main_screen.Hilt_MainFragment.generatedComponent(Hilt_MainFragment.java:80)
    at com.nikolam.main_feature.presenter.main_screen.Hilt_MainFragment.inject(Hilt_MainFragment.java:102)
    at com.nikolam.main_feature.presenter.main_screen.Hilt_MainFragment.initializeComponentContext(Hilt_MainFragment.java:63)
    at com.nikolam.main_feature.presenter.main_screen.Hilt_MainFragment.onAttach(Hilt_MainFragment.java:55)
    at androidx.fragment.app.Fragment.onAttach(Fragment.java:1783)
    at com.nikolam.main_feature.presenter.main_screen.Hilt_MainFragment.onAttach(Hilt_MainFragment.java:45)
    at androidx.fragment.app.Fragment.performAttach(Fragment.java:2911)
    at androidx.fragment.app.FragmentStateManager.attach(FragmentStateManager.java:464)
    at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:275)
    at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
    at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100)
    at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1971)
    at androidx.fragment.app.BackStackRecord.commitNow(BackStackRecord.java:305)
    at com.nikolam.colorme.main_feature.MainFragmentTest$whenMainActivityLaunchedNavigatorIsInvokedForFragment$$inlined$launchFragmentInHiltContainer$1.perform(HiltExt.kt:46)
    at androidx.test.core.app.ActivityScenario.lambda$onActivity$2$ActivityScenario(ActivityScenario.java:660)
    at androidx.test.core.app.ActivityScenario$$Lambda$4.run(Unknown Source)
    at androidx.test.core.app.ActivityScenario.onActivity(ActivityScenario.java:670)
    at com.nikolam.colorme.main_feature.MainFragmentTest.whenMainActivityLaunchedNavigatorIsInvokedForFragment(MainFragmentTest.kt:85)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at dagger.hilt.android.internal.testing.MarkThatRulesRanRule$1.evaluate(MarkThatRulesRanRule.java:106)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:575)
    at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:263)
    at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

Now here is my setup.现在这是我的设置。

Dependencies依赖项

    testImplementation(TestLibraryDependency.HILT_ANDROID_TESTING)
    kaptTest(TestLibraryDependency.HILT_ANDROID_TESTING_COMPILER)
    testImplementation(TestLibraryDependency.TEST_RUNNER)
    testImplementation(TestLibraryDependency.ESPRESSO_CORE)
    testImplementation(TestLibraryDependency.ANDROIDX_TEST_RULES)
    testImplementation(TestLibraryDependency.ANDROIDX_CORE_TESTING)
    testImplementation(TestLibraryDependency.ANDROIDX_TEST_EXT)

This is my test这是我的测试

@HiltAndroidTest
@Config(application = HiltTestApplication::class, maxSdk = Build.VERSION_CODES.P)
@RunWith(RobolectricTestRunner::class)
class MainFragmentTest {

    @get:Rule()
    var hiltAndroidRule = HiltAndroidRule(this)

    @Before
    fun init() {
        hiltAndroidRule.inject()
    }

    @Test
    fun whenMainActivityLaunchedNavigatorIsInvokedForFragment() {
     //   launchActivity()
        // GIVEN - On the home screen
        val navController = mock(NavController::class.java)

        var fragment = launchFragmentInHiltContainer<MainFragment>() {
            Navigation.setViewNavController(this.view!!, navController)
        }

        // WHEN - Click on the "+" button
        onView(withId(R.id.add_floating_action)).perform(ViewActions.click())

        // THEN - Verify that we navigate to the add screen
        verify(navController).navigate(
            Uri.parse(UPLOAD_DEEPLINK)
        )
    }

Launch in hilt container per google 在每个谷歌的刀柄容器中启动

inline fun <reified T : Fragment> launchFragmentInHiltContainer(
    fragmentArgs: Bundle? = null,
    @StyleRes themeResId: Int = R.style.FragmentScenarioEmptyFragmentActivityTheme,
    crossinline action: Fragment.() -> Unit = {}
) {
    val startActivityIntent = Intent.makeMainActivity(
        ComponentName(
            ApplicationProvider.getApplicationContext(),
            HiltTestActivity::class.java
        )
    ).putExtra(EmptyFragmentActivity.THEME_EXTRAS_BUNDLE_KEY, themeResId)

    ActivityScenario.launch<HiltTestActivity>(startActivityIntent).onActivity { activity ->
        val fragment: Fragment = activity.supportFragmentManager.fragmentFactory.instantiate(
            Preconditions.checkNotNull(T::class.java.classLoader),
            T::class.java.name
        )
        fragment.arguments = fragmentArgs
        activity.supportFragmentManager
            .beginTransaction()
            .add(android.R.id.content, fragment, "")
            .commitNow()

        fragment.action()
    }
}

(I also have their custom runner) (我也有他们的自定义跑步者)

I also have a debug source set that contains HiltTestActivity like here, alongside debug manifest. 我还有一个调试源集,其中包含像这里一样的 HiltTestActivity,以及调试清单。

Besides this, I'd like to somehow inject and initialize my NavigationManager (wrapper class around navController) in my Activity.除此之外,我想以某种方式在我的 Activity 中注入和初始化我的 NavigationManager(围绕 navController 的包装器 class)。 Is there a way to achieve this?有没有办法做到这一点? When I tried to use my MainActivity for tests I kept getting errors because my lateinit @Injects weren't getting initialized...当我尝试使用我的 MainActivity 进行测试时,我不断收到错误,因为我的 lateinit @Injects 没有被初始化......

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding;

    private lateinit var navController : NavController
    @Inject
    lateinit var navManager: NavManager

    private fun initNavManager() {
        navManager.setOnNavEvent {
            navController.navigate(it)
        }

In my case I had to use就我而言,我不得不使用

    hilt {
        enableTransformForLocalTests = true
    }

Since the Roboelectric/ Hilt has 20 bugs currently being tracked it was hard to pinpoint what workaround was the case:)由于 Roboelectric/Hilt 目前正在跟踪 20 个错误,因此很难确定是什么解决方法:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Hilt Fragments 必须附加到 @AndroidEntryPoint Activity。 找到:class androidx.fragment.app.testing.FragmentScenario$EmptyFragmentActivity - Hilt Fragments must be attached to an @AndroidEntryPoint Activity. Found: class androidx.fragment.app.testing.FragmentScenario$EmptyFragmentActivity Hilt Fragments 必须附加到 @AndroidEntryPoint Activity。 找到:class - Hilt Fragments must be attached to an @AndroidEntryPoint Activity. Found: class java.lang.IllegalStateException:必须将 Hilt 活动附加到找到的 @AndroidEntryPoint 应用程序:class dv.file.transh.app.FileExplorer - java.lang.IllegalStateException: Hilt Activity must be attached to an @AndroidEntryPoint Application Found: class dv.file.transh.app.FileExplorer android片段没有附加到活动 - android Fragment not attached to activity Android-片段未附加到活动 - Android - Fragment not attached to activity 片段 MyFragment 未附加到 Activity - Fragment MyFragment not attached to Activity 加载适配器时片段未附加到活动 - Fragment not attached to Activity while loading adapter 片段未附加到活动,位于onResume中 - Fragment not attached to Activity, in onResume 片段未附加到活动 - Fragment not attached to Activity 片段未附加到 AlertDialog 中的活动 - Fragment not attached to Activity in AlertDialog
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM