如何使用Espresso在特定位置测试适配器中的项目

时间:2014-12-23 15:59:28

标签: android android-adapter android-espresso

我正在尝试使用Espresso(2.0)来验证给定位置的列表适配器项中的文本是否正确,并且在我的生命中我无法找出正确的调用方法。 / p>

我的适配器类型(IconRowAdapter)包含IconRow个对象的列表。每个IconRow都有一个getText()方法,可以返回该项目的文本。

这是非Espresso工作测试代码,用于验证适配器中位置0处的IconRow对象是否具有预期文本(“艺术家”)。

public void testHomeActivityMenu() {
    ListView list = (ListView) getActivity().findViewById(R.id.item_list);
    IconRowAdapter adapter = (IconRowAdapter) list.getAdapter();

    assertEquals(adapter.getItem(0).getText(), "Artists");
}

这很有效。

我尝试了以下Espresso代码的各种变体来做同样的事情,

onData(is(instanceOf(IconRowAdapter.class)))
        .atPosition(0)
        .check(matches(withItemContent("Artists")));

withItemContent()看起来像这样:

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);
        }
    };
}

我期望这样做:

  • 从适配器获取数据,该适配器是IconRowAdapter的一个实例(活动中只有一个实例)......
  • ...找到适配器中位置0的条目......
  • ...使用withItemContent()检查该位置的项目中的文本是否与“艺术家”匹配

当我运行时,我收到以下错误:

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]>

IconRowAdapter中有12个项目,所以我有信心它正在寻找正确的适配器。

我能够找到的所有示例代码和文档都假设您正在尝试在适配器中查找条目以便单击它(并且这将导致其他视图中的值更改)。我找不到任何有关如何检查适配器中给定项的值的内容。

感激地收到了任何见解。

编辑添加:

以下是什么工作:

onData(anything())
        .inAdapterView(withId(R.id.item_list))
        .atPosition(0)
        .check(matches(hasDescendant(
                allOf(withId(R.id.text1), withText(containsString("Artists"))))));

如果我理解正确测试R.id.text1视图的值,而不是适配器中的值。我想这对于UI测试是有意义的,但我仍然有兴趣了解如何(如果?)我可以使用Espresso来测试适配器中项目的内容。

2 个答案:

答案 0 :(得分:4)

作为onData()的参数传递的匹配器必须与Adapter.getItem()返回的值匹配。 因此第一个版本不匹配,因为使用了错误的类型。它应该是:

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

在不同类型的CharSequences上使用equalTo也可能是一个陷阱。 String是CharSequence,但是如果IconRow.getText()返回CharSequence而不是String,那么它也可以是Spannable,Editable等,在这种情况下equalTo将不匹配。因此,如果IconRow.getText()返回除String之外的任何内容,请确保在比较之前将其转换为String。

答案 1 :(得分:0)

尝试这一点必须有效:

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

如果删除atPosition(0),那么您只需检查适配器视图中的状态。