如何通过工具测试来测试抽象的android片段?

时间:2018-06-25 09:20:39

标签: android unit-testing android-fragments mockito

我的任务是通过工具测试来测试抽象片段https://github.com/Mobile-Connect/android_sdk_v3/blob/develop/Application/src/main/java/com/gsma/mobileconnect/r2/android/demo/fragments/BaseAuthFragment.java。而且我完全不知道该怎么做。

我已经阅读了一些教程,但这是唯一的基础。.所以,现在我有一些想法:

  1. 1)我应该使用 ActivityTestRule ,因为我需要一个活动来 加上我的片段。
  2. 2)我的课程(片段)是抽象的,因此     与之沟通,我从中继承了我的测试课,然后我     创建我的测试类实例以使用片段的方法。

所以,现在我有这样的结构:

@RunWith(AndroidJUnit4.class)
public class BaseAuthFragment_ExampleTest extends BaseAuthFragment{

    @Override
    public void onComplete(DiscoveryResponse discoveryResponse) {}

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);
    private MainActivity mainActivity = null;
    BaseAuthFragment fragment = null;

    @Before
    public void setUp() {
        //MockitoAnnotations.initMocks(this);
        mainActivity = mActivityRule.getActivity();
    }

    @After
    public void setDown() {
        mainActivity = null;
        fragment = null;
    }

    @Test
    public void useAppContext() throws Exception {
        assertNotNull(mainActivity);
        FragmentManager fragmentManager = mainActivity.getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragment = new BaseAuthFragment_ExampleTest();
        MobileConnectAndroidView as = BaseAuthFragment.mobileConnectAndroidView;
        fragmentTransaction.add(fragment, null);
        fragmentTransaction.commit();

        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                getActivity().getSupportFragmentManager().executePendingTransactions();
            }
        });

        getInstrumentation().waitForIdleSync();

        fragment.connectMobileDemo();
        MobileConnectAndroidView as2 = BaseAuthFragment.mobileConnectAndroidView;
        assertThat(as, is(as2));
    }
}

我想在第一种方法的示例( connectMobileWithoutDiscovery )上解释我的想法:

  1. 首先设置了 mobileConnectConfig ,但是它受到保护。 因此,对于我来说,有两种选择:
    • 跳过此测试
    • 尝试使用反射在方法调用之前和之后获取此对象中的差异。 (也许我甚至可以尝试模拟返回的值 诸如withClientSecret和withCacheResponsesWithSessionId之类的方法,以及 检查是否已使用正确的参数调用它。)
  2. 然后我们可以看到 setupMobileConnect 方法的调用,但是 它也是私有的,我不知道我是否应该使用一些外部库 像powermockito来检查它是否被调用,或者我应该检查一下 方法调用静态字段之前和之后 在此方法中设置的 mobileConnectAndroidView

所以,我只想知道我的想法是否正确。

1 个答案:

答案 0 :(得分:1)

BaseAuthFragment是一个抽象片段,显然是要被子类化。在我看来,正确的测试将像您所做的那样涉及一个子类,但该子类可能应该是嵌套类同一包的同级兄弟,而不是测试本身。这将为您提供一些有关将来对BaseAuthFragment进行更改是否需要更改子类的反馈,因为您已经创建了该测试子类。

大概是,您的被测片段可以跟踪已调用的方法(否则可能需要Mockito监视),并公开获取程序的状态,否则该方法将被隐藏,或者希望子类进行跟踪,否则您需要根据方法调用顺序进行推断。

此外,通过制作用于测试的Fragment(但这不是您的测试),您可以随意扩展有限可见性方法(protected)的可见性。就是说,如果您遵循将测试与被测类放在同一程序包中的做法(可能位于不同的源文件夹中),则仍可以访问这些方法而无需更改可见性:protected受保护程度较低而不是默认的包专用可见性级别。