34

I have this code in my Espresso test

onView(withId(R.id.src))
    .perform(click());
onData(hasToString(startsWith("CCD")))
    .perform(click());
onView(withId(R.id.src))
    .check(matches(withText(containsString("CCD"))));

What I'm trying to do is to click the item in the Spinner and check if it's indeed selected in the Spinner.

But I'm getting this error:

android.support.test.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: 'with text: a string containing "CCD"' doesn't match the selected view. Expected: with text: a string containing "CCD" Got: "AppCompatSpinner{id=2131558533, res-name=src, visibility=VISIBLE, width=528, height=163, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}"

JJD
  • 50,076
  • 60
  • 203
  • 339
Jezer Crespo
  • 2,152
  • 3
  • 24
  • 27
  • In test spresso documentation they show a solution to select a item inside the spinner from its index position I think is the right way... URL : https://github.com/vgrec/EspressoExamples/blob/master/app/src/androidTest/java/com/vgrec/espressoexamples/SpinnerSelectionTest.java – Javier Gutiérrez-Maturana Sánc May 21 '17 at 08:30

4 Answers4

83

Replace withText() with withSpinnerText()

onView(withId(spinnerId)).perform(click());
onData(allOf(is(instanceOf(String.class)), is(selectionText))).perform(click());
onView(withId(spinnerId)).check(matches(withSpinnerText(containsString(selectionText))));

Reference: https://code.google.com/p/android-test-kit/issues/detail?id=85

Jonas
  • 2,096
  • 20
  • 17
  • what is the selectionText here?? – Mukesh Garg Oct 01 '16 at 11:24
  • That's a string - the spinner text, the same one that is visible to user. – Jonas Oct 06 '16 at 07:17
  • How do I just grab the Spinner object itself and have my way with it, without using these accessor methods? Or is that forbidden due to threads, or the other standard Android excuses? – Phlip Jun 17 '19 at 21:14
  • 1
    This link unfortunately is broken. @Jonas any idea what the correct link supposed to be? – Leonardo Sibela Aug 12 '21 at 18:05
  • 1
    Can't find the correct link anymore. In the link there was an error report and fix for it. Generally just using matcher function withSpinnerText() should solve the issue these days and details in link were just additional historical info. Long time ago espresso did not have withSpinnerText(). – Jonas Aug 19 '21 at 10:14
  • Thank you so much, worked like a charm. I wasn't willing to go through clumsy Espresso API docs to find the solution. You saved my ton of time. I wish these APIs were bit straight forward to work with because on a surface level these nested calls make zero sense. – MG Developer Sep 05 '22 at 18:04
14

Really simple solution that worked out for me .....without using matcher for CustomSpinner

onView(withId(R.id.custom_spinner)).perform(click());
onData(anything()).atPosition(1).perform(click());
onView(withId(R.id.custom_spinner)).check(matches(withSpinnerText(containsString("yourstring"))));
JJD
  • 50,076
  • 60
  • 203
  • 339
ArpitA
  • 721
  • 7
  • 17
  • 1
    This seems more straight-forward than the accepted answer. What makes the accepted answer better than this? (especially since the accepted answer references a dead link) – MKE Oct 23 '21 at 16:47
4

For custom adapter i had yo create a custom matcher:

 onView(withId(R.id.spinner)).perform(click());
 onData(allOf(is(instanceOf(YourCustomClass.class)), withMyValue("Open"))).perform(click());


public static <T> Matcher<T> withMyValue(final String name) {
    return new BaseMatcher<T>() {
        @Override
        public boolean matches(Object item) {
            return item.toString().equals(name);
        }

        @Override
        public void describeTo(Description description) {

        }
    };
}

Then you must override toString() method on your custom class.

Renato Probst
  • 5,914
  • 2
  • 42
  • 45
0

This works for me

 private void selectSpinnerItem(final int resId, final String selection) {
    onView(withId(resId)).perform(click());
    onData(hasToString(selection)).perform(click());
    onView(withId(resId)).check(matches(withSpinnerText(containsString(selection))));
}
Josef Vancura
  • 1,053
  • 10
  • 18