我想在Espresso Testing
上运行Android project
步骤1-找到我的RecyclerView
第2步,检查RecyclerView
上的项目
第一步成功运行,但第二步应检查recycler view
项目失败。.
onView(withRecyclerView(R.id.recyclerView_recipes).atPosition(0))
.check(matches(isDisplayed()));
onView(withRecyclerView(R.id.recyclerView_recipes).atPositionOnView(0, R.id.tv_recipe_name))
.check(matches(isDisplayed()))
.check(matches(withText("Nutella Pie")));
package com.example.android.advancebakingapp.Adapter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.android.advancebakingapp.Activity.RecipeFragment;
import com.example.android.advancebakingapp.MainActivity;
import com.example.android.advancebakingapp.Model.Ingredient;
import com.example.android.advancebakingapp.Model.Recipe;
import com.example.android.advancebakingapp.R;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import java.util.List;
public class RecipeAdapter extends
RecyclerView.Adapter<RecipeAdapter.RecipeAdapterViewHolder> {
private Context context;
private ArrayList<Recipe> mRecipes;
private RecipeOnClickHandler mRecipeOnClickHandler;
public static final String INGREDIENTS = "mIngredients";
public static final String INGREDIENTS_BUNDLE = "ingredientsBundle";
public RecipeAdapter(RecipeOnClickHandler recipeOnClickHandler) {
mRecipeOnClickHandler = recipeOnClickHandler;
}
public void setRecipesData(ArrayList<Recipe> recipeData) {
mRecipes = recipeData;
notifyItemRangeChanged(0, mRecipes.size());
// notifyDataSetChanged();
}
@Override
public RecipeAdapter.RecipeAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
// Inflate the custom layout
View contactView = inflater.inflate(R.layout.row_recipe, parent, false);
// Return a new holder instance
RecipeAdapterViewHolder viewHolder = new RecipeAdapterViewHolder(contactView);
return viewHolder;
}
@Override
public void onBindViewHolder(RecipeAdapter.RecipeAdapterViewHolder viewHolder, int position) {
Recipe recipe = mRecipes.get(position);
String imageUrl = mRecipes.get(position).getImage();
TextView tv = viewHolder.mTextView;
viewHolder.mIngredients = mRecipes.get(position).getIngredients();
tv.setText(recipe.getName());
if (imageUrl.equals("") && imageUrl.isEmpty())
{
Picasso.with(context).load(R.drawable.baking_app_ico).into(viewHolder.mImageView);
}
else
{
Picasso.with(context).load(imageUrl).into(viewHolder.mImageView);
}
}
// Returns the total count of items in the list
@Override
public int getItemCount() {
if(mRecipes == null) {
return 0;
}
return mRecipes.size();
}
public class RecipeAdapterViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final ImageView mImageView;
public final TextView mTextView;
private List<Ingredient> mIngredients;
public RecipeAdapterViewHolder(View view) {
super(view);
mImageView = (ImageView) view.findViewById(R.id.iv_recipe_image);
mTextView = (TextView) view.findViewById(R.id.tv_recipe_name);
view.setOnClickListener(this);
}
@Override
public void onClick(View view) {
int position = getAdapterPosition();
Recipe selectedRecipe = mRecipes.get(position);
mRecipeOnClickHandler.onClickRecipe(selectedRecipe);
}
}
public interface RecipeOnClickHandler {
void onClickRecipe(Recipe recipe);
}
}
java.lang.NullPointerException: Attempt to read from field 'android.view.View android.support.v7.widget.RecyclerView$ViewHolder.itemView' on a null object reference
at com.example.android.advancebakingapp.RecyclerViewMatcher$1.matchesSafely(RecyclerViewMatcher.java:53)
at com.example.android.advancebakingapp.RecyclerViewMatcher$1.matchesSafely(RecyclerViewMatcher.java:26)
at org.hamcrest.TypeSafeMatcher.matches(TypeSafeMatcher.java:65)
at android.support.test.espresso.base.ViewFinderImpl$MatcherPredicateAdapter.apply(ViewFinderImpl.java:127)
at android.support.test.espresso.core.internal.deps.guava.collect.Iterators$5.computeNext(Iterators.java:639)
at android.support.test.espresso.core.internal.deps.guava.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:141)
at android.support.test.espresso.core.internal.deps.guava.collect.AbstractIterator.hasNext(AbstractIterator.java:136)
at android.support.test.espresso.base.ViewFinderImpl.getView(ViewFinderImpl.java:68)
at android.support.test.espresso.ViewInteraction$2.call(ViewInteraction.java:273)
at android.support.test.espresso.ViewInteraction$2.call(ViewInteraction.java:265)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
我尝试更改adapter ViewHolder
,但失败。
这是我在GitHub上的项目: https://github.com/haya51033/AdvanceBakingApp 请帮忙?
答案 0 :(得分:1)
尽管我的建议SystemClock.sleep(1000)
为您效劳,但更多的是解决方法,而不是解决方案。真正的问题在于,当Espresso用文本断言视图时,它还不存在,因此睡眠会有所帮助。
一种更好的方法是使用RecyclerViewActions
包中的espresso-contrib
,因为它需要更多的时间来加载RecyclerView(它等待主循环空闲),因此您不需要自行实现(例如,放入SystemClock.sleep(...)
)。因此,您的测试可能如下所示:
onView(withId(R.id.recyclerView_recipes)).perform(RecyclerViewActions.actionOnItemAtPosition(0, isDisplayed()));
onView(withId(R.id.recyclerView_recipes)).perform(RecyclerViewActions.actionOnItemAtPosition(0, Matchers.allOf(withText("Nutella Pie"), isDisplayed())));
有关更多信息,请在此处查看文档-
https://developer.android.com/training/testing/espresso/lists#recycler-view-list-items