如何测试片段使用的Activity实现的接口?

时间:2017-05-23 09:25:07

标签: android android-fragments testing android-espresso

我有Activity,其中包含两个片段。一个片段有EditTextButton;单击按钮时,将使用编辑框中的文本调用回调:

// Not showing implementation of onCreateView()
class HelloEditFragment extends Fragment implements View.OnClickListener {
  interface OnListener {
    void onValue(String value);
  }

  private OnListener mListener;

  public void onAttach(Context context) {
    mListener = (OnListener) context;
  }

  public void onClick(View v) {
    mListener.onValue(mEditText.getText().toString();
  }
}

我的Activity实现了OnListener:

class HelloActivity extends Activity implements HelloEditFragment.OnListener {
  public void onValue(String value) {
    // ...
  }
}

到目前为止,我的测试看起来像这样:

@RunWith (AndroidJUnit4.class)
public class HelloEditFragmentTest {

  @Rule
  public ActivityTestRule<HelloActivity> mActivityRule = new ActivityTestRule<> (HelloActivity.class);

  @Test
  public void testActivity () {
    onView (withId (R.id.edit_text_hello_edit)).perform (typeText ("hello"));
    onView (withId (R.id.button_hello_edit)).perform (click ());
    // Now what?
  }
}

如果单击片段中的按钮,如何检查是否调用onValue()回调?谢谢,

1 个答案:

答案 0 :(得分:2)

没有一种简单的方法可以做到这一点。我建议您放弃interface实施的Activity并改为使用字段监听器。

E.g。像这样:

class HelloActivity extends Activity {

    HelloEditFragment.OnListener listener = new HelloEditFragment.OnListener() {
        @Override
        public void onValue(String value) {
            // ...
        }
    };

    public HelloEditFragment.OnListener getListener() {
        return listener;
    }

    //... everything else
}

class HelloEditFragment extends Fragment implements View.OnClickListener {

    public void onAttach(Context context) {
        if (context instanceof HelloActivity) {
            mListener = ((HelloActivity) context).getListener();
        }
    }

    //... everything else (including onDetach with clearing the listener)
}

然后您可以轻松模拟您的现场监听器:

@RunWith (AndroidJUnit4.class)
public class HelloEditFragmentTest {

    @Rule
    public ActivityTestRule<HelloActivity> mActivityRule = new ActivityTestRule<> (HelloActivity.class);

    @Test
    public void testActivity () {
        HelloEditFragment.OnListener listener = Mockito.mock(HelloEditFragment.OnListener.class);
        mActivityRule.getActivity().listener = listener;

        onView (withId (R.id.edit_text_hello_edit)).perform (typeText ("hello"));
        onView (withId (R.id.button_hello_edit)).perform (click ());

        Mockito.verify(listener, Mockito.times(1)).onValue("hello");
        Mockito.verifyNoMoreInteractions(listener);
    }
}