How to use Espresso testing Recycler view in a fragment getting data with volley using IdlingResource

Viewed 2128

will, I have a MainActivity That Holds MainFragment, MainFragment implements a RecipeDataFetcher callback interface that brings data got through Volley/network in RecipeDataFetcher Class. MainFragment has a recyclerview that is suppose to display a couple of recipes cards

-I need to execute a test on a RecyclerView item

Here's my main fragment`public class

MainFragment extends Fragment implements RecipesRecyclerAdapter.OnRecipeItemSelected,
        RecipesDataFetcher.RecipesFetcherDataListener {

    private View v;
    private RecipesDataFetcher recipesDataFetcher;
    private OnFragmentInteractionListener mListener;

private RecyclerView recyclerView;
private RecipesRecyclerAdapter recipesRecyclerAdapter;
private Recipes mRecipes;
private RecyclerView.LayoutManager layoutManager;


private SimpleIdlingResource mIdlingResource;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    v = inflater.inflate(R.layout.fragment_main, container, false);
    mRecipes = new Recipes();
    recyclerView = (RecyclerView) v.findViewById(R.id.rv_recipes);
    if (mTwoPanel) {
        layoutManager = new GridLayoutManager(getActivity(), 2);
    } else {
        layoutManager = new LinearLayoutManager(getActivity());
    }

    recipesRecyclerAdapter = new RecipesRecyclerAdapter(this, mRecipes);
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setAdapter(recipesRecyclerAdapter);
    return v;
}

@VisibleForTesting
@NonNull
public SimpleIdlingResource getIdlingResource() {
    if (mIdlingResource == null) {
        mIdlingResource = new SimpleIdlingResource();
    }
    return mIdlingResource;
}



   @Override
    public void onSaveInstanceState(Bundle outState) {
//        super.onSaveInstanceState(outState);
    }
@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        mListener = (OnFragmentInteractionListener) context;
    } else {
        throw new RuntimeException(context.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}

@Override
public void onItemSelected(int itemPosition) {
    mListener.onFragmentInteraction(mRecipes.get(itemPosition), mRecipes.size());
}

@Override
public void onResume() {
    super.onResume();
    if (mRecipes.isEmpty()) {
        getData();
    }
}

@Override
public void onConnectionFailure() {
    if (!checkOnlineState(getActivity())) {
        Logging.shortToast(getActivity(), getString(R.string.internet_error));
    } else {
        Logging.shortToast(getActivity(), getString(R.string.server_error));
    }
}

private void getData() {
    recipesDataFetcher = new RecipesDataFetcher(getActivity(), this);
    recipesDataFetcher.getRecipes(mIdlingResource);
}

@Override
public void onConnectionDone(Recipes recipes) {

    mRecipes.addAll(recipes);
    recipesRecyclerAdapter.notifyDataSetChanged();

    //TODO: Do bulk inset in a background thread and for once
    ContentValues[] contentValues = new ContentValues[recipes.size()];
    for (int i = 0; i < recipes.size(); i++) {
        ContentValues contentValue = new ContentValues();
        Gson gson = new Gson();
        String ingredients = gson.toJson(recipes.get(i).getIngredients());
        String steps = gson.toJson(recipes.get(i).getSteps());
        contentValue.put(COLUMN_RECIPE_INGREDIENTS, ingredients);
        contentValue.put(COLUMN_RECIPE_STEPS, steps);
        contentValue.put(COLUMN_RECIPE_SERVINGS, recipes.get(i).getServings());
        contentValue.put(COLUMN_RECIPE_IMAGE, recipes.get(i).getImage());
        contentValue.put(COLUMN_RECIPE_NAME, recipes.get(i).getName());
        contentValues[i] = contentValue;
    }

    getContext().getContentResolver().bulkInsert(CONTENT_URI, contentValues);

    if(mIdlingResource!=null){
        mIdlingResource.setIdleState(true);
    }

}


public interface OnFragmentInteractionListener {
    void onFragmentInteraction(Recipe recipe, int size);
}`

and here is my dataFetching class

public class RecipesDataFetcher extends BaseDataFetcher {
    public RecipesDataFetcher(Context context, BaseDataFetcherListener mListener) {
        super(context, mListener);
    }



    public void getRecipes(SimpleIdlingResource simpleIdlingResource) {
            if(simpleIdlingResource!=null){
            simpleIdlingResource.setIdleState(false);}
        String URL = BaseURL;
    Logging.log("getCountries: " + URL);
    JsonArrayRequest jsonObjReq = new JsonArrayRequest(URL, (JSONArray jsonArr) -> {
        Logging.log("getCountries response: " + jsonArr.toString());
        Recipes recipes = new Recipes(jsonArr);
        ((RecipesFetcherDataListener) mListener).onConnectionDone(recipes);
        if(simpleIdlingResource!=null){
            simpleIdlingResource.setIdleState(true);
        }
    }, this.errorListener);
    retryPolicy(jsonObjReq);
    getReQ().add(jsonObjReq);
}

public interface RecipesFetcherDataListener extends BaseDataFetcherListener {
    void onConnectionDone(Recipes recipes);
}

}

An Here is My testing class

 @RunWith(AndroidJUnit4.class)
    public class MyFragmentTest {   

        private SimpleIdlingResource mIdlingResource;

    @Rule
    public FragmentTestRule<MainFragment> mFragmentTestRule = new FragmentTestRule<>(MainFragment.class);

    @Before
    public void registerIdlingResource() {
        // Launch the activity to make the fragment visible
        mFragmentTestRule.launchActivity(null);
         mIdlingResource = mFragmentTestRule.getFragment().getIdlingResource();
        Espresso.registerIdlingResources(mIdlingResource);
    }

    @Test
    public void fragment_can_be_instantiated() {


        // Then to test item in position 0
        onView(withId(R.id.rv_recipes))
                .perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));
    }

    //  unregister resources
    @After
    public void unregisterIdlingResource() {
        if (mIdlingResource != null) {
            Espresso.unregisterIdlingResources(mIdlingResource);
        }
    }
}

And Finally here is the whole code project, just let me know what am i doing wrong exactly :D, Your help would be highly appreciated.

1 Answers
Related