espresso dynamic spinner testing
Asked Answered
T

2

8

I am trying to test a dynamically generated Spinner. I am able to click on the spinner but then I need to select an option from the list with a given text that is shown (I found out from hierarchyviewer that a PopupWindow is shown but am unable to get to the required text which is offscreen). The spinner uses an ArrayAdapter of custom objects (code below),

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Spinner mySpinner = (Spinner) findViewById(R.id.my_spinner);
        List<MyValue> list = Arrays.asList(
                new MyValue("One", "1"),
                new MyValue("Two", "2"),
                new MyValue("Three", "3"),
                new MyValue("Four", "4"),
                new MyValue("Five", "5"),
                new MyValue("Six", "6"),
                new MyValue("Seven", "7"),
                new MyValue("Eight", "8"),
                new MyValue("Nine", "9"),
                new MyValue("Ten", "10"),
                new MyValue("Eleven", "11"),
                new MyValue("Twelve", "12"),
                new MyValue("Thirteen", "13"),
                new MyValue("Fourteen", "14"),
                new MyValue("Fifteen", "15"),
                new MyValue("Sixteen", "16"),
                new MyValue("Seventeen", "17"),
                new MyValue("Eighteen", "18"),
                new MyValue("Nineteen", "19"),
                new MyValue("Twenty", "20"),
                new MyValue("Twenty One", "21")
        );

        final ArrayAdapter<MyValue> adapter = new ArrayAdapter<>(this,
                R.layout.dropdown_selected_item,
                list);
        mySpinner.setAdapter(adapter);
        mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                Log.d("MySpinnerTest", "current = " + adapter.getItem(position));
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {}
        });
    }

    public class MyValue {
        String name;
        String code;

        public MyValue(String name, String code) {
            this.name = name;
            this.code = code;
        }

        @Override
        public String toString() {
            return name;
        }
    }
}

I tried with onData(withSpinnerText("Twenty")).perform(click()) but get a PerformException and I tried to find out how else to match the correct view based on a given text, in the spinner popupwindow but could not figure out how to do this.

Any help would be greatly appreciated.

TIA

Tetraploid answered 31/10, 2015 at 23:8 Comment(1)
Is it possible to attach a perform exception that you see and withSpinnerText matcher?Saccharate
T
4

Found a way to do this and so posting the answer to my own question.

I had to create a custom matcher for my object and then use that with the onData()

public static Matcher<Object> withMyValue(final String expectedName) {
    return new BoundedMatcher<Object, MyValue>(MyValue.class) {

        @Override
        public void describeTo(Description description) {
            description.appendText("with expectedName: " + expectedName);
        }

        @Override
        protected boolean matchesSafely(MyValue myValue) {
            return myValue.getName().equalsIgnoreCase(expectedName);
        }
    };
}

which then could be used as (after clicking on the spinner to display the dropdown)

onData(withMyValue(field.name)).perform(click());

Tetraploid answered 21/11, 2015 at 13:30 Comment(0)
V
0

It seems your Spinner has no dropdown view, before mySpinner.setAdapter(adapter);

Please add this line :

adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Valerle answered 12/11, 2015 at 14:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.