I am trying to use Espresso (2.0) to verify that the text in the list item in the given position is correct, and for my life I cannot find the correct methods to call.
My adapter type ( IconRowAdapter ) contains a list of IconRow objects. Each IconRow has a getText() method that returns the text of this element.
The non-Espresso test code works here, which verifies that the IconRow object at position 0 in the adapter has the expected text ("Artists").
public void testHomeActivityMenu() { ListView list = (ListView) getActivity().findViewById(R.id.item_list); IconRowAdapter adapter = (IconRowAdapter) list.getAdapter(); assertEquals(adapter.getItem(0).getText(), "Artists"); }
It works.
I tried various options on the following espresso code to do the same,
onData(is(instanceOf(IconRowAdapter.class))) .atPosition(0) .check(matches(withItemContent("Artists")));
where withItemContent() as follows:
public static Matcher<Object> withItemContent(String expectedText) { checkNotNull(expectedText); return withItemContent(equalTo(expectedText)); } @SuppressWarnings("rawtypes") public static Matcher<Object> withItemContent(final Matcher<String> itemTextMatcher) { checkNotNull(itemTextMatcher); return new BoundedMatcher<Object, IconRow>(IconRow.class) { @Override public boolean matchesSafely(IconRow iconRow) { return itemTextMatcher.matches(iconRow.getText()); } @Override public void describeTo(Description description) { description.appendText("with item content: "); itemTextMatcher.describeTo(description); } }; }
What do I expect from this:
- Get data from the adapter, that instance of IconRowAdapter (of which there is only one in activity) ...
- ... find the entry at position 0 in the adapter ...
- ... use withItemContent () to verify that the text in the element at this position matches "Artists"
When I run, I get the following error:
Caused by: java.lang.RuntimeException: No data found matching: is an instance of uk.org.ngo.squeezer.IconRowAdapter contained values: <[Data: uk.org.ngo.squeezer.IconRowAdapter$IconRow@b1585980 (class: uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 0, Data: uk.org.ngo.squeezer.IconRowAdapter$IconRow@b15859e0 (class: uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 1, Data: uk.org.ngo.squeezer.IconRowAdapter$IconRow@b1585a00 (class: uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 2, Data: uk.org.ngo.squeezer.IconRowAdapter$IconRow@b1585a20 (class: uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 3, Data: uk.org.ngo.squeezer.IconRowAdapter$IconRow@b1585a40 (class: uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 4, Data: uk.org.ngo.squeezer.IconRowAdapter$IconRow@b1585a60 (class: uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 5, Data: uk.org.ngo.squeezer.IconRowAdapter$IconRow@b1585a80 (class: uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 6, Data: uk.org.ngo.squeezer.IconRowAdapter$IconRow@b1585aa0 (class: uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 7, Data: uk.org.ngo.squeezer.IconRowAdapter$IconRow@b1585ac0 (class: uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 8, Data: uk.org.ngo.squeezer.IconRowAdapter$IconRow@b1585ae0 (class: uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 9, Data: uk.org.ngo.squeezer.IconRowAdapter$IconRow@b1585b00 (class: uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 10, Data: uk.org.ngo.squeezer.IconRowAdapter$IconRow@b1585b20 (class: uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 11]>
There are 12 elements in the IconRowAdapter, so I'm sure it is looking for the right adapter.
All the sample code and documentation that I could find suggests that you are trying to find the entry in the adapter to click on it (and this will cause the value to change in another view change). I can not find anything that says how to check the value of this element in the adapter.
Any ideas gratefully received.
Edit to add:
What is work:
onData(anything()) .inAdapterView(withId(R.id.item_list)) .atPosition(0) .check(matches(hasDescendant( allOf(withId(R.id.text1), withText(containsString("Artists"))))));
If I understand correctly, that checking the value of the view R.id.text1, and not the value in the adapter. I assume this makes sense for a UI test, but I'm still interested in knowing how (if?) I can use Espresso to check the contents of an element in an adapter.