首页 > 解决方案 > 使用反射为私有方法编写测试

问题描述

我有一堂课是NetworkManager。我有很多private方法,我真的需要为它们编写测试。

起初我没有找到任何解决方案来为我的私有方法编写测试。无论如何,我找到了一种访问我的私有方法并为它们编写一些测试的方法。

我使用反射来访问我的函数并为它们编写测试。有一个简单的私有方法的例子:

 private String myFun (String input){
        return input+"hello";
    }

有一个测试类,我在其中使用了反射:

@RunWith(AndroidJUnit4.class)
public class NetworkManagerTest {

    private static NetworkManager networkManager;
    private Context appContext = InstrumentationRegistry.getTargetContext();

    private @ADType
    int adType = ADType.TYPE_BANNER;


    @BeforeClass
    public static void setup() {

        getInstrumentation().runOnMainSync(new Runnable() {
            @Override
            public void run() {

                networkManager = NetworkManager.getInstance();
                networkManager.addNetworkCall(TestUtil.getSampleSystemRequest());

            }
        });
    }

    @Test
    public void sample() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        Method method = NetworkManager.class.getDeclaredMethod("myFun", String.class);
        method.setAccessible(true);
        String output = (String) method.invoke(networkManager, "Ehsan");

        Assert.assertEquals("Ehsanhello", output);
    }

}

这很好用。但问题是这种方式可以为使用反射的私有方法编写测试多少?

有没有更好的方法来实现这个目标?

标签: androidtestingtddandroid-testing

解决方案


但问题是这种方式可以为使用反射的私有方法编写测试多少?

有没有更好的方法来实现这个目标?

最常见的方法是放弃该目标。

从历史上看,TDD 的重点一直是验证行为,而不是实现细节。部分原因是测试让我们可以自信地更改代码的内部设计,因为测试会提醒我们任何意外的行为变化。

因此,如果我们需要一个测试来确保某些私有方法中的逻辑是正确的,我们会找到一个依赖于该逻辑的公共 API 的用例,并编写测量公共 API 行为的测试。

我们可以通过将临时故障注入私有方法并验证测试是否检测到故障来校准测试。

完成后,我们可以选择通过内联私有方法来重构代码;在这种情况下,所有测试都应该通过,因为我们没有改变测试对象的行为——我们只是移动了细节。

如果您要积极努力改进应用程序的内部设计,那么您需要与该内部设计分离的测试。


推荐阅读