单元测试时的 ClassCastException onAttach() Android 片段

ClassCastException onAttach() when unit testing Android Fragment

我正在尝试测试一个片段,该片段具有必须由托管 Activity 实现的接口,并通过 onAttach().

转换为该特定接口的类型

问题:我不确定如何在 Android 单元测试中实现必要的接口方法,或者是否有必要这样做。令人惊讶的是,我没有找到任何解决此问题的帖子或论坛。

测试:

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();
    }

}

片段:

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");
        }
    }

    ...

}

但是当我尝试 运行 一个简单的测试时,我得到 :

java.lang.ClassCastException: com.example.package.ActivityForUnitTesting@1234567 must implement ExampleFragmentListener at com.example.package.ExampleFragment.onAttach(ExampleFragment.java:)

我知道问题是我的单元测试 ActivityForUnitTesting 对象没有实现所需的接口方法。我的问题是,如何在我的单元测试中安全地实现这些方法。我没有运气找到类似的问题或可靠的例子。

我没有找到解决这个问题的方法,但我确实找到了 "workaround"。不要使用 onAttach(),而是通过 public 方法显式设置您的侦听器。

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;
    }

    ...

}

那么,您应该已经在您的主机中实现了 ExampleFragmentListener Activity。只需致电

setExampleFragmentListener(ActivityOrClassThatImplementsExampleFragmentListener)

从您执行 Activity 设置的任何地方。因此,测试不应该抱怨未实现的方法。