如何在Espresso中直接断言ListAdapter的Data对象而非视图?
在Espresso中直接断言ListAdapter数据项的优雅实现
核心实现方案
我们可以通过自定义ViewAssertion直接校验Adapter中的原始数据,完全绕过视图渲染的依赖,避免本地化、格式配置带来的断言误差。
1. 封装复用的工具方法
import android.view.View; import android.widget.AdapterView; import androidx.test.espresso.NoMatchingViewException; import androidx.test.espresso.ViewAssertion; import org.hamcrest.Matcher; public class DataAssertions { public static ViewAssertion matchesData(Matcher<Object> dataMatcher) { return (view, noViewFoundException) -> { // 处理视图未找到的异常 if (noViewFoundException != null) { throw noViewFoundException; } // 获取所在的AdapterView及对应数据项 AdapterView<?> adapterView = (AdapterView<?>) view.getParent(); int position = adapterView.getPositionForView(view); Object dataItem = adapterView.getAdapter().getItem(position); // 用传入的数据Matcher执行断言 if (!dataMatcher.matches(dataItem)) { throw new AssertionError(String.format("数据项不符合预期: 实际值为%s", dataItem.toString())); } }; } }
2. 简洁调用
借助上面的工具方法,你可以像伪代码期望的那样优雅地完成数据断言:
onData(FooMatcher.withId(5)) .check(DataAssertions.matchesData(FooMatcher.withQuantity(10)));
方案说明
- 直接从Adapter中获取原始
Foo对象,完全脱离视图渲染逻辑的影响,断言结果更可靠。 - 封装的
matchesData方法是通用型工具,可适配所有AdapterView的数据源断言,只需传入对应的数据Matcher即可。 - 保留Espresso原有API风格,调用逻辑直观易懂,无需额外学习成本。
针对RecyclerView的补充(可选)
如果你的ListAdapter用于RecyclerView,可调整工具方法适配RecyclerView的结构:
import android.view.View; import androidx.recyclerview.widget.RecyclerView; import androidx.test.espresso.NoMatchingViewException; import androidx.test.espresso.ViewAssertion; import org.hamcrest.Matcher; public class DataAssertions { public static ViewAssertion matchesRecyclerViewData(Matcher<Object> dataMatcher) { return (view, noViewFoundException) -> { if (noViewFoundException != null) { throw noViewFoundException; } RecyclerView recyclerView = (RecyclerView) view.getParent().getParent(); int position = recyclerView.getChildAdapterPosition(view); Object dataItem = recyclerView.getAdapter().getItem(position); if (!dataMatcher.matches(dataItem)) { throw new AssertionError(String.format("数据项不符合预期: 实际值为%s", dataItem.toString())); } }; } }
内容的提问来源于stack exchange,提问作者TaylanKammer
相关产品推荐
相关产品推荐

