使用Hilt进行UI测试时提示未添加HiltAndroidRule但已添加的问题
解决Hilt测试中"The component was not created"的问题
我一眼就看出问题出在哪了——这是JUnit Rule的执行顺序搞的鬼!
你虽然已经添加了HiltAndroidRule,但代码里同时存在HiltAndroidRule和ActivityTestRule两个@Rule,JUnit 4默认的Rule执行逻辑并不能保证Hilt的Rule先运行。而ActivityTestRule会自动帮你启动目标Activity,如果这时候Hilt还没完成组件初始化和注入操作,就会抛出你遇到的IllegalStateException,因为Hilt的依赖注入组件还没准备好为Activity提供依赖。
解决方案:用RuleChain明确指定Rule执行顺序
我们需要用RuleChain来强制让HiltAndroidRule先执行,确保Hilt组件在Activity启动前就完成初始化。修改后的代码如下:
@RunWith(AndroidJUnit4.class) @UninstallModules(ItemsModule.class) @HiltAndroidTest public class SelectItemActivityTest { private final HiltAndroidRule hiltRule = new HiltAndroidRule(this); private final ActivityTestRule<SelectItemActivity> activityRule = new ActivityTestRule<>(SelectItemActivity.class); @Rule public RuleChain ruleChain = RuleChain .outerRule(hiltRule) .around(activityRule); @Before public void init() { hiltRule.inject(); } @BindValue public List<Item> items = getItems(); // 改为public确保Hilt能访问到绑定值 List<Item> getItems() { List<Item> items = new ArrayList<>(); items.add(new Item(1, "Item1", "", true, true, true)); items.add(new Item(2, "Item2", "", true, true, true)); items.add(new Item(3, "Item3", "", true, true, true)); return items; } @Test public void text_isDisplayed() { onView(withText("Item1")).check(matches(isDisplayed())); } }
关键修改点说明:
- RuleChain顺序控制:
outerRule指定的Rule会优先执行,这里让HiltAndroidRule先完成组件初始化,再执行ActivityTestRule启动Activity,从根本上避免了组件未创建的问题。 - @BindValue字段访问性:把
items字段改为public,Hilt需要直接访问这个测试绑定的依赖,私有字段可能导致Hilt无法识别到你的自定义绑定值。
这样修改后,Hilt就能在Activity启动前完成组件创建和依赖注入,你的测试应该就能正常运行了!
内容的提问来源于stack exchange,提问作者Questioner
相关产品推荐
相关产品推荐

