android-浓咖啡-检查RecyclerView项目是否正确订购
作者:互联网
如何使用Espresso检查RecyclerView项目是否以正确的顺序显示?我正在尝试通过对每个元素的标题的文本进行检查来对其进行测试.
当我尝试这段代码时,它可以单击该元素,但是不能继续执行,而不能执行单击以尝试断言该元素的文本
onView(withId(R.id.rv_metrics)).perform(actionOnItemAtPosition(0, click()));
当我尝试使用自定义匹配器时,我不断收到错误消息
Error performing 'load adapter data' on view 'with id: mypackage_name:id/rv_metrics'
我现在知道onData不适用于RecyclerView,但在此之前,我试图为该任务使用自定义匹配器.
public static Matcher<Object> hasTitle(final String inputString) {
return new BoundedMatcher<Object, Metric>(Metric.class) {
@Override
protected boolean matchesSafely(Metric metric) {
return inputString.equals(metric.getMetric());
}
@Override
public void describeTo(org.hamcrest.Description description) {
description.appendText("with title: ");
}
};
}
我也尝试过类似的方法,但是由于将类型指定为actionOnItemAtPosition方法的参数,因此它显然不起作用,但是我们是否有类似的方法可以起作用?
onView(withId(R.id.rv_metrics)).check(actionOnItemAtPosition(0, ViewAssertions.matches(withText("Weight"))));
我在这里想念什么?
非常感谢.
解决方法:
正如提到的here,RecyclerView对象的工作方式不同于AdapterView对象,因此onData()不能用于与其交互.
为了在RecyclerView的特定位置找到视图,您需要实现一个自定义RecyclerViewMatcher
,如下所示:
public class RecyclerViewMatcher {
private final int recyclerViewId;
public RecyclerViewMatcher(int recyclerViewId) {
this.recyclerViewId = recyclerViewId;
}
public Matcher<View> atPosition(final int position) {
return atPositionOnView(position, -1);
}
public Matcher<View> atPositionOnView(final int position, final int targetViewId) {
return new TypeSafeMatcher<View>() {
Resources resources = null;
View childView;
public void describeTo(Description description) {
String idDescription = Integer.toString(recyclerViewId);
if (this.resources != null) {
try {
idDescription = this.resources.getResourceName(recyclerViewId);
} catch (Resources.NotFoundException var4) {
idDescription = String.format("%s (resource name not found)",
new Object[] { Integer.valueOf
(recyclerViewId) });
}
}
description.appendText("with id: " + idDescription);
}
public boolean matchesSafely(View view) {
this.resources = view.getResources();
if (childView == null) {
RecyclerView recyclerView =
(RecyclerView) view.getRootView().findViewById(recyclerViewId);
if (recyclerView != null && recyclerView.getId() == recyclerViewId) {
childView = recyclerView.findViewHolderForAdapterPosition(position).itemView;
}
else {
return false;
}
}
if (targetViewId == -1) {
return view == childView;
} else {
View targetView = childView.findViewById(targetViewId);
return view == targetView;
}
}
};
}
}
然后以这种方式在测试用例中使用它:
@Test
void testCase() {
onView(new RecyclerViewMatcher(R.id.rv_metrics)
.atPositionOnView(0, R.id.txt_title))
.check(matches(withText("Weight")))
.perform(click());
onView(new RecyclerViewMatcher(R.id.rv_metrics)
.atPositionOnView(1, R.id.txt_title))
.check(matches(withText("Height")))
.perform(click());
}
标签:android,android-recyclerview,android-espresso 来源: https://codeday.me/bug/20191012/1897565.html