5

I'm trying to test a fragment using Robolectric. The fragment contains the code:

public class MyDialogFragment extends DialogFragment {

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            // Verify that the host activity implements the callback interface
            try {
                // Instantiate the MyDialogListener so we can send events to the host
                this.setListener((MyDialogListener) getActivity());
            } catch (ClassCastException e) {
                throw new ClassCastException(getActivity().toString()
                        + " must implement MyDialogListener");
            }
        }
    }

This pattern of fragments making sure their owners implement their listeners is pretty common in Android. I'm currently creating my fragment and activity in my @Test like so:

fragment = MyDialogFragment.newInstance(/* Some params */);

FragmentActivity activity = Robolectric
        .buildActivity(FragmentActivity.class)
        .create().start()
        .resume().get();
shadowActivity = shadowOf(activity);

FragmentManager fragmentManager = activity.getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
        .beginTransaction();
fragment.show(fragmentManager, "MyDialogFragment");
fragmentTransaction.commit();

Of course, this throws a CastClassException because FragmentActivity doesn't implement MyDialogFragmentListener.

How can I test this using Robolectric?

So far, I've tried asking the ActivityManager to check if we're running in a test, like so:

if (!ActivityManager.isRunningInTestHarness()) {
   throw new ClassCastException(getActivity().toString()
        + " must implement MyDialogFragmentListener");
}

But that doesn't seem to work with my test setup.

I've also considered making a MyDialogFragmentTestActivity class that extends FragmentActivity and implements MyDialogFragmentListener, with empty methods. This will probably work, but doesn't feel clean to me. I'd rather not create classes only used for tests.

Is there any better way to do test this fragment, using JUnit, Robolectric and Mockito?

clay_to_n
  • 583
  • 3
  • 15
  • You don't want to create a simple subclass of FragmentActivity that implements the needed interface? That seems pretty straightforward to me. – Doug Stevenson Mar 02 '16 at 01:54
  • 1
    I think you're right. I created a subclass in my test directory, and am just using that instead of FragmentActivity.class when building the activity. I don't like needing an extra file hanging around for the tests, but it's pretty contained and clear. Thanks. – clay_to_n Mar 02 '16 at 18:58
  • Also don't modify your production code to satisfy tests – Eugen Martynov Mar 02 '16 at 20:00
  • In my project also similar requirement is there, any solution for this? – ashok reddy Oct 17 '16 at 04:14

0 Answers0