微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决Hilt Fragment 必须附加到@AndroidEntryPoint Activity,同时测试它附加到@AndEntPoint 标记的Activity

我关注了很多教程/文章googles architecture sample

无论我尝试什么,我都会收到一个错误提示我需要将 Fragment 附加到 @AndroidEntryPoint 注释的 Activity。我已经正确设置了所有内容,但仍然无法正常工作。

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)

在这是我的设置。

依赖

    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)

这是我的测试

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

除此之外,我想以某种方式在我的 Activity 中注入和初始化我的 NavigationManager(围绕 navController 的包装类)。有没有办法实现这一目标?当我尝试使用 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)
        }

解决方法

就我而言,我不得不使用

    hilt {
        enableTransformForLocalTests = true
    }

由于 Roboelectric/Hilt 目前正在跟踪 20 个错误,因此很难确定是什么解决方法:)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。