使用反射为私有方法编写测试

Use Reflection to Write test for private methods

我有一个 class 即 NetworkManager。我有很多 private 方法,我确实需要为它们编写测试。

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

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

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

有一个测试class,我在里面用到了反射:

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

}

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

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

But the question is how much is this way okay to write test for private methods with using of reflection?

Is there a better way to achieve this goal?

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

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

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

的行为

我们可以通过在私有方法中注入临时错误来校准测试,并验证测试是否检测到错误。

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

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

我热衷于说如果你有太多的私有方法要测试,这意味着你的 class 有太多的责任。私有方法可以按逻辑分组并提取到其他 classes.

这就是我不接受 Guava 的 @VisibleForTesting 注释的原因。