[英]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.