Cómo afirmar dentro de un RecyclerView en Espresso?

Estoy usando espresso-contrib para realizar acciones en un RecyclerView , y funciona como debería, por ejemplo:

 onView(withId(R.id.recycler_view)) .perform(RecyclerViewActions.actionOnItemAtPosition(0, click())); //click on first item 

Y necesito hacer afirmaciones sobre ella. Algo como esto:

 onView(withId(R.id.recycler_view)) .perform(RecyclerViewActions.actionOnItemAtPosition(0, check(matches(withText("Test Text")))); 

Pero, como RecyclerViewActions está, por supuesto, esperando una acción, dice un tipo de argumento incorrecto de 2º. No hay RecyclerViewAssertions en espresso-contrib.

¿Hay alguna forma de realizar afirmaciones en una vista de reciclador?

Usted debe comprobar la solución de Danny Roa Custom RecyclerView Acciones Y lo utilizan de esta manera:

 onView(withRecyclerView(R.id.recycler_view) .atPositionOnView(1, R.id.ofElementYouWantToCheck)) .check(matches(withText("Test text"))); 

Muy fácil. No se necesita biblioteca adicional. Hacer:

  onView(withId(R.id.recycler_view)) .check(matches(atPosition(0, withText("Test Text")))); 

Con el método que puede poner en su clase Utils .

 public static Matcher<View> atPosition(final int position, @NonNull final Matcher<View> itemMatcher) { checkNotNull(itemMatcher); return new BoundedMatcher<View, RecyclerView>(RecyclerView.class) { @Override public void describeTo(Description description) { description.appendText("has item at position " + position + ": "); itemMatcher.describeTo(description); } @Override protected boolean matchesSafely(final RecyclerView view) { RecyclerView.ViewHolder viewHolder = view.findViewHolderForAdapterPosition(position); if (viewHolder == null) { // has no item on such position return false; } return itemMatcher.matches(viewHolder.itemView); } }; } 

Si el elemento puede no ser visible en la pantalla al principio, desplácese a él antes:

  onView(withId(R.id.recycler_view)) .perform(scrollToPosition(87)) .check(matches(atPosition(87, withText("Test Text")))); 

Sólo para mejorar la respuesta de riwnodennyk, si su ViewHolder es un ViewGroup lugar de un objeto de View directa como TextView , puede agregar hasDescendant matcher para que coincida con el objeto TextView en ViewGroup . Ejemplo:

 onView(withId(R.id.recycler_view)) .check(matches(atPosition(0, hasDescendant(withText("First Element"))))); 

He estado luchando en el mismo problema donde tengo una opinión del reciclador con 6 artículos y entonces tengo que elegir el en la posición 5 y el 5to uno no es visible en la visión.
La solución anterior también funciona. Además, sé que es un poco tarde pero pensamos que vale la pena compartir.

Hice esto con una solución simple como abajo:

 onView(withId(R.id.recylcer_view)) .perform(RecyclerViewActions.actionOnItem( hasDescendant(withText("Text of item you want to scroll to")), click())); 

RecyclerViewActions.actionOnItem – Realiza una ViewAction en una vista comparada por viewHolderMatcher .

  1. Desplazar RecyclerView a la vista comparada por itemViewMatcher
  2. Realizar una acción en la vista combinada

Más detalles se pueden encontrar en: RecyclerViewActions.actionOnItem

En mi caso, era necesario fusionar la solución de Danny Roa y riwnodennyk:

 onView(withId(R.id.recyclerview)) .perform(RecyclerViewActions.scrollToPosition(80)) .check(matches(atPositionOnView(80, withText("Test Test"), R.id.targetview))); 

Y el método:

 public static Matcher<View> atPositionOnView(final int position, final Matcher<View> itemMatcher, @NonNull final int targetViewId) { return new BoundedMatcher<View, RecyclerView>(RecyclerView.class) { @Override public void describeTo(Description description) { description.appendText("has view id " + itemMatcher + " at position " + position); } @Override public boolean matchesSafely(final RecyclerView recyclerView) { RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(position); View targetView = viewHolder.itemView.findViewById(targetViewId); return itemMatcher.matches(targetView); } }; } 

La solución de Danny Roa es impresionante, pero no funcionó para los elementos fuera de pantalla que acababa de desplazarse. La solución reemplaza esto:

 View targetView = recyclerView.getChildAt(this.position) .findViewById(this.viewId); 

con este:

 View targetView = recyclerView.findViewHolderForAdapterPosition(this.position) .itemView.findViewById(this.viewId); 

… en la clase TestUtils .

  • Cómo analizar datos de 2 URL diferentes mediante el método asyncTask
  • ¿Es IntentService una implementación del patrón de comandos?
  • Calcular Pi en un teléfono Android
  • TextColor vs TextColorPrimary vs TextColorSecondary
  • El objeto se convierte en nulo
  • Cómo obtener un mensaje de devolución de servicio de Android desde un plugin de teléfono
  • El wrap_content de ImageView no funciona con Glide
  • Excluyendo índices de un HashMap
  • Cómo hacer un Libgdx Bitmapfont de modo que es el color de los píxeles es la inversa del fondo?
  • ¿Hay alguna biblioteca de edición de video disponible en Android
  • Uso de la opción de generación de Java useLegacyMergeSort = true con android gradle
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.