Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hilt dependency injection for UI testing says "HiltAndroidRule" wasn't added but it was

I'm trying to use Hilt for dependency injection but it gives the error java.lang.IllegalStateException: The component was not created. Check that you have added the HiltAndroidRule. The HiltAndroidRule is added though:

@RunWith(AndroidJUnit4.class)
@UninstallModules(ItemsModule.class)
@HiltAndroidTest
public class SelectItemActivityTest {

    @Rule
    public HiltAndroidRule hiltRule = new HiltAndroidRule(this);

    @Before
    public void init() {
        hiltRule.inject();
    }
    @BindValue
    List<Item> items = getItems();
    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;
    }

    @Rule
    public ActivityTestRule<SelectItemActivity> mActivityRule =
            new ActivityTestRule<>(SelectItemActivity.class);

    @Test
    public void text_isDisplayed() {
        onView(withText("Item1")).check(matches(isDisplayed()));
    }
}

I've also tried adding an ItemsModule inside the class but that had the same result.

like image 943
Questioner Avatar asked Jul 09 '20 11:07

Questioner


2 Answers

You must wrap it using RuleChain or by applying order parameter to the Rule Annotation.

It is explained in detail here: https://developer.android.com/training/dependency-injection/hilt-testing#multiple-testrules

like image 177
user3482211 Avatar answered Oct 24 '22 07:10

user3482211


I was having the same error when I was trying to test an activity that was not the launcher one. I am using Kotlin, but something very similar should apply to Java.

Let's say you want to test MyActivity. First you need to define your ActivityTestRule as a not launch activity:

val targetContext: Context = InstrumentationRegistry.getInstrumentation().targetContext

@get:Rule(order = 0) 
var hiltRule = HiltAndroidRule(this)

@get:Rule(order = 1) 
var testRule = ActivityTestRule(MyActivity::class.java, false, false)

And then, launch your activity, after hilt injection:

@Before fun setup() {
    hiltRule.inject()
    testRule.launchActivity(Intent(targetContext, MyActivity::class.java))
}
like image 45
Seven Avatar answered Oct 24 '22 07:10

Seven