Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Espresso RecyclerView Error - No view holder at position

I'm running an Espresso test to click on an element of the RecyclerView.

   onView(withId(R.id.recyclerList)).perform(RecyclerViewActions.actionOnItemAtPosition(2, click()));

However, I'm getting the following error: java.lang.IllegalStateException: No view holder at position

I've checked the view id is pointing to my RecyclerView and my dependencies are as follows:

  • com.android.support.test.espresso:espresso-core:2.2.2
  • com.android.support.test.espresso:espresso-contrib:2.2.2
like image 320
Adam Hurwitz Avatar asked Aug 13 '17 19:08

Adam Hurwitz


1 Answers

Ok, I think I had the same problem and I managed to solve it.

The problem was that unless you are using an AsyncTask to populate the RecyclerView, Espresso doesn't wait for the background thread to complete before performing the next operation.

So, it would search for the item at position 2, and since your background thread is still running and the recycler view hasn't loaded yet, it would return the IllegalStateException.

Even though I wouldn't suggest using this, you can check if the test works very quickly, by adding a Thread.sleep() (with a reasonable time), like this:

    @Test
    public void myTest() {

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        onView(withId(R.id.recyclerList))
                .perform(RecyclerViewActions.actionOnItemAtPosition(2, click()));

        //assert something
}

The better (and correct) solution to this problem, is using Idling Resources.

This short and concise video really helped me understand how to use IdlingResources (CountingIdlingResources in particular).

Your ui test should now look something like:

    @Test
    public void myTest() {
        registerIdlingResources(/*put your IdlingResource here*/);

        onView(withId(R.id.recyclerList))
                .perform(RecyclerViewActions.actionOnItemAtPosition(2, click()));

        //assert something
}

I hope it helped.

like image 138
ovalb Avatar answered Sep 28 '22 01:09

ovalb