You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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()));
    }
}

关键修改点说明:

  1. RuleChain顺序控制:outerRule指定的Rule会优先执行,这里让HiltAndroidRule先完成组件初始化,再执行ActivityTestRule启动Activity,从根本上避免了组件未创建的问题。
  2. @BindValue字段访问性:把items字段改为public,Hilt需要直接访问这个测试绑定的依赖,私有字段可能导致Hilt无法识别到你的自定义绑定值。

这样修改后,Hilt就能在Activity启动前完成组件创建和依赖注入,你的测试应该就能正常运行了!

内容的提问来源于stack exchange,提问作者Questioner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 12:57:32