How to use Espresso to check an element in an adapter at a specific position

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.

+5
source share
2 answers

Matches passed as the onData() argument must match the value returned by Adapter.getItem() . Thus, the first version does not match, due to the wrong type. It should be:

 onData(is(instanceOf(IconRowAdapter.IconRow.class))) 

What could also be a trap, uses equalTo for different types of CharSequences. String is CharSequence, but if IconRow.getText () returns CharSequence instead of String, then it could also be Spannable, Editable, etc., And in this case equalTo will not match. Therefore, if IconRow.getText () returns anything other than String, be sure to convert it to a string before comparing.

+3
source

Try this, it should work:

 //check that item is present in list at position 0 onData(withItemContent("Artists")) .inAdapterView(withId(R.id.list_view)) .atPosition(0) .check(matches(isDisplayed())); 

If you remove atPosition(0) , you just check for the presence of the adapter in the view.

0
source

Source: https://habr.com/ru/post/1209780/


All Articles