关于java:JUnit:如何提供公开所有方法以便进行测试

JUnit: How to provide making all my methods public in order to be tested

我开始在我的项目中使用JUnit和Mockito,我很快注意到的是我最终将我的私有方法转换为public以便从测试类中加入,这是一个糟糕的解决方案。

有时仅测试公共方法就足够了,但有时我也想测试一些内部方法。 这有解决方法吗? 例如,一个特殊的注释,允许JUnit将私有方法模拟为公共或类似的东西?


直接测试私有方法的需要是一种设计气味。在设计良好的类中,所有功能都是可访问的,合理的,因此可通过其公共接口进行测试。

缺乏这通常意味着你的课程太大而复杂,试图同时处理多个职责。对此的最佳解决方案是重构:将一些功能提取到一个单独的类中,在那里它可以公开获得,因此可以直接进行单元测试。


您的公共方法必须调用您的私有方法。
因此,您可以通过创建公共方法的测试函数来测试您的私有方法。

如果您仍想通过Junits测试私有函数,可以使用reflection来完成。

您必须设置方法setAccessible==true.的属性

例:

1
2
3
4
5
6
7
8
 public void testisvalid() throws Exception
    {
        MyHandler handler = new MyHandler();
        Method privateStringMethod = MyHandler.class.getDeclaredMethod("isvalid", Long.class);
        privateStringMethod.setAccessible(true);
        String =  (String) privateStringMethod.invoke(handler, 852l );
        assertNotNull(s);
    }

getDeclaredMethod中,您必须提供private方法的名称,以及您在函数中按顺序传递的arguments的类型。


要问的第一个问题是:这些私有方法是否可以成为其他帮助程序类的公共接口的一部分。在这种情况下,您可以测试此帮助程序类,并在原始类中注入模拟帮助程序。

如果它不可能,那么使这些私有方法受到保护,记录它们仅受保护以便进行测试并且不应该被子类调用或覆盖它们的事实,并将测试类放在与类相同的包装中在测试中能够访问这种受保护的方法。

在这种情况下,我使用Guava提供的@VisibleForTesting注释。


我的maven构建基础结构为测试源提供了一个单独的目录,但具有相同的包结构。因此,如果方法不公开但可以访问包,那就足够了。