【问题标题】:Guava @VisibleForTesting : Help me with a complete exampleGuava @VisibleForTesting:帮我举一个完整的例子
【发布时间】:2014-07-25 22:22:15
【问题描述】:

我的意图是对私有方法进行单元测试,并且我了解如何导入 @VisibleForTesting 并将其用于私有方法。我进行了相当多的搜索,但无法看到演示此功能的完整示例。

例如:

class MyClass {
    @VisibleForTesting 
    private double[] getWorkArray(double[] values,int length) {
               :
               :
        return <some double array> 
    }
}

现在在 JUnit 中,我必须能够做到

@Test
public void testProvateMethod() {
    MyClass object = new MyClass();
    assertNotNull(object.getWorkArray(...);
}

但困难的部分是我无法理解/执行以下操作 a) maven 编译器插件的片段,用于包含相关的注释处理器 b) 实际上能够测试私有方法。 (因为它会引发与方法可见性相关的错误)

我在 JUnit 中编写测试时无法执行此操作(由于私有访问错误)。例如:mvn clean test

请提供一个完整的示例,说明完成私有方法的 JUnit 测试所涉及的所有步骤。

【问题讨论】:

  • 不要这样做。通过公共方法测试私有方法。如果这太复杂,则表明您在班级中承担了太多责任。考虑提取一个类,它将以前的私有方法公开为公共方法。
  • 这里的问题是2折。
  • 这里的问题是关于给定开始和结束索引的数组的简单转换,我认为这比在代码中我需要的每个地方内联这些行更值得我自己的方法。还有一点相关:假设我将这些相关方法提取到私有静态嵌套类中;我将如何测试 privat 静态类的方法。

标签: java maven unit-testing guava


【解决方案1】:

测试私有方法一定是不好的模式之一。 但是,有时您经常会感到测试私有方法的冲动。 在这种情况下,我个人使用 ReflectionTestUtils 来测试方法。这是因为我们想保持私有方法的初衷,只测试方法。下面是我的示例。

MyClass myClass = new MyClass();

ReflectionTestUtils.invokeMethod(myClass, "getWorkArray", values, length);

一个缺点是我将方法的名称作为字符串获取,这有点令人难过,除了重构在 IDEA 中无法正确转换。

希望对你有帮助。

谢谢。

【讨论】:

    【解决方案2】:

    您可以删除private关键字:

    class MyClass{
          @VisibleForTesting double[] getWorkArray(double[] values,int length) {
                     :
                     :
               return <some double array> 
           }
    }
    

    那么你可以:

    MyClass object = new MyClass();
    assertNotNull(object.getWorkArray(...);
    

    在你的测试中。

    【讨论】:

    • 这不是解决方案,而是解决方法。问题是:“我的意图是对私有方法进行单元测试”——这样它们就不再是私有的了。
    【解决方案3】:

    首先,我建议测试私有方法,单元测试在大多数情况下应该测试公共方法。如果您必须测试私有方法,通常表明设计不佳。

    关于 @VisibleForTesting ,它用于 Guava 的包方法中,而不是 JUnit API 的一部分。注释只是一个标记,表明该方法可以测试,它甚至不会加载到 JVM 中。因此,如果您需要测试非公共方法,使方法包范围对同一包中的单元测试类可见。

    最后,通过使用反射可以访问私有方法,如果你真的需要测试它们。

    【讨论】:

    • 您的意思是@VisibleForTesting 仅用于记录目的,使用它并没有任何可操作的后果。我希望会有某种注释处理器(可能是编译时间)来进行测试,但不能用于生产。
    • 是的,@VisibleForTesting 信息只是存储在类文件中,而不是加载到 JVM 中。
    • 我认为如果在没有特定标志的情况下编译,应该使用编译时挂钩(例如源代码生成)来失败。
    猜你喜欢
    • 2016-06-07
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    • 2017-03-31
    • 1970-01-01
    相关资源
    最近更新 更多