I'm trying to test a Fragment that has in interface that must be implemented by the hosting Activity and gets casted to that specific interface's type through onAttach()
.
Problem: I'm not sure how to implement the necessary interface methods within an Android Unit Test or if it's even necessary to do so. Surprisingly, I haven't found any posts or forums that address this issue.
Test:
public class FragmentTest {
private ActivityForUnitTesting fragmentHostActivity;
private ExampleFragment fragmentToTest;
@Rule
public ActivityTestRule activityTestRule = new ActivityTestRule<>(ActivityForUnitTesting.class);
@Before
public void setUp() {
fragmentHostActivity = (ActivityForUnitTesting) activityTestRule.getActivity();
fragmentManager = fragmentHostActivity.getSupportFragmentManager();
fragmentToTest = new ExampleFragment();
}
@Test
public void testExample() {
fragmentManager.beginTransaction()
.replace(R.id.frame_layout_container, fragmentToTest)
.commit();
}
}
Fragment:
public class ExampleFragment extends Fragment {
private ExampleFragmentListener exampleFragmentListener;
...
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
exampleFragmentListener = (ExampleFragmentListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement ExampleFragmentListener");
}
}
...
}
but when I try running a simple test I get:
java.lang.ClassCastException: com.example.package.ActivityForUnitTesting@1234567 must implement ExampleFragmentListener at com.example.package.ExampleFragment.onAttach(ExampleFragment.java:)
I know that the issue is that my Unit Test ActivityForUnitTesting object does not implement the required interface methods. My question is, how do I safely implement those methods within my Unit Test. I haven't had any luck finding a similar question or a solid example.
I didn't find a solution to this, but I did find a "workaround". Instead of using onAttach()
, explicitly set your listener through a public method.
public class ExampleFragment extends Fragment {
private ExampleFragmentListener exampleFragmentListener;
...
//@Override
//public void onAttach(Context context) {
// super.onAttach(context);
// try {
// exampleFragmentListener = (ExampleFragmentListener) context;
// } catch (ClassCastException e) {
// throw new ClassCastException(context.toString() + " must implement ExampleFragmentListener");
// }
//}
public void setExampleFragmentListener(ExampleFragmentListener exampleFragmentListener) {
this.exampleFragmentListener = exampleFragmentListener;
}
...
}
then, you should already have ExampleFragmentListener implemented in your host Activity. Just call
setExampleFragmentListener(ActivityOrClassThatImplementsExampleFragmentListener)
from wherever you perform your Activity setup. As a result, the test shouldn't complain about unimplemented methods.