Espresso Android testing - using getActivity in a helper method (can't find method to import)

943 views Asked by At

I'm testing an Android app with Espresso. I'm trying to write a helper function in a helper class that can check the value of a spinner with the following code:

public static void assertSpinner(MainActivity activity, int id, int val) {
    Spinner s = (Spinner) activity.findViewById(id);
    assertNotNull(s);
    assertEquals(val, s.getSelectedItemPosition());
}

I can then call the helper from my test with:

assertSpinner(getActivity(),R.id.someSpinner,12);

Though it seems weird that every assertSpinner's first arg is getActivity(). I'd like to call getActivity() in the helper function instead so I don't need to pass it, but it seems that is only made available because the test extends ActivityInstrumentationTestCase2. Is there any way to get this value without having to pass it to each of my helpers, or does that not fit the Android way?

1

There are 1 answers

3
Daniel Lubarov On BEST ANSWER

No, I don't think there's a clean/easy way to get the current Activity from outside of a test.

However, you could do this cleanly with a custom view matcher. Something like

static Matcher<View> withSelectedItemPosition(final int selectedItemPosition) {
  return new BoundedMatcher<View, Spinner>(Spinner.class) {
    @Override protected boolean matchesSafely(Spinner spinner) {
      return spinner.getSelectedItemPosition() == selectedItemPosition;
    }

    @Override public void describeTo(Description description) {
      description.appendText("with selected item position: ")
          .appendValue(selectedItemPosition);
    }
  };
}

Then you could do

onView(withId(R.id.my_spinner)).check(matches(withSelectedItemPosition(5)));

It's a bit of extra code, but more idiomatic. Espresso really discourages you from interacting with the view hierarchy directly; ideally your tests should never call methods like findViewById.