Java JUnit:如何提供将所有方法公开以供测试的功能

Java JUnit:如何提供将所有方法公开以供测试的功能,java,unit-testing,junit,mocking,Java,Unit Testing,Junit,Mocking,我开始在我的项目中使用JUnit和Mockito,我很快注意到,我最终将我的私有方法转换为公共方法,以便从测试类中访问,这是一个糟糕的解决方案 有时只测试公共方法就足够了,但有时我也想测试一些内部方法。有解决办法吗?例如,一个特殊的注释允许JUnit将私有方法模拟为public或类似的东西 您的公共方法必须调用您的私有方法。 因此,您可以通过为公共方法生成一个测试函数来测试您的私有方法 如果您仍然希望通过Junits测试私有函数,可以使用反射 您必须设置方法的属性setAccessible==t

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


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

您的公共方法必须调用您的私有方法。 因此,您可以通过为公共方法生成一个测试函数来测试您的私有方法

如果您仍然希望通过Junits测试私有函数,可以使用
反射

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

例如:

 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
方法的名称,以及按顺序传递函数的
参数的类型。

您的公共方法必须调用您的private方法。 因此,您可以通过为公共方法生成一个测试函数来测试您的私有方法

如果您仍然希望通过Junits测试私有函数,可以使用
反射

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

例如:

 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
方法的名称,以及按顺序传递函数
参数的类型。

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


缺少这一点通常意味着您的类太大太复杂,试图同时处理多个职责。最好的解决方案是重构:将一些功能提取到一个单独的类中,在这个类中它可以公开使用,因此可以直接进行单元测试。

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


缺少这一点通常意味着您的类太大太复杂,试图同时处理多个职责。最好的解决方案是重构:将一些功能提取到一个单独的类中,在这个类中,它可以公开使用,因此可以直接进行单元测试。

要问的第一个问题是:这些私有方法是否可以作为附加帮助器类的公共接口的一部分。在这种情况下,您可以测试这个helper类,并在原始类中注入一个mock helper

如果不可能,那么就让这些私有方法受到保护,记录这样一个事实,即它们只为了被测试而受到保护,并且它们不应该被子类调用或重写,并将测试类与被测试的类放在同一个包中,以便能够访问这个受保护的方法


在本例中,我使用了Guava提供的
@VisibleForTesting
注释。

要问的第一个问题是:这些私有方法是否可以作为附加帮助器类的公共接口的一部分。在这种情况下,您可以测试这个helper类,并在原始类中注入一个mock helper

如果不可能,那么就让这些私有方法受到保护,记录这样一个事实,即它们只为了被测试而受到保护,并且它们不应该被子类调用或重写,并将测试类与被测试的类放在同一个包中,以便能够访问这个受保护的方法


在本例中,我使用Guava提供的
@VisibleForTesting
注释。

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

我的maven build infrastructure为测试源提供了一个单独的目录,但具有相同的包结构。因此,如果这些方法不是公共的,而是包可访问的,就足够了。

不需要将它们公开,只需将它们设置为包保护(无限定符:“void testFoo()”),并将测试放在同一个包中。无需将它们公开,只需将它们设置为包保护(无限定符:“void testFoo()”)把你的测试放在同一个包里。答案很好。如果您专注于测试行为,而不是代码行,您将永远不会希望您的测试类调用您的私有方法。如果您专注于测试行为,而不是代码行,您将永远不会希望您的测试类调用您的私有方法。IMHO反射应该是最后的手段。请看@Peter我知道这是一种不好的做法。第一行答案给出了另一种解决方案。但我已经告诉过OP是否仍然想测试junits的私有函数,然后使用反射。很高兴我们在这一点上达成了一致:-)但从你的答案来看(至少对我来说)并不清楚,所以我认为提一下是有用的。我认为反思应该是最后的手段。请看@Peter我知道这是一种不好的做法。第一行答案给出了另一种解决方案。但我已经告诉过OP是否还想测试junits的私有函数,然后使用反射。很高兴我们在这一点上达成了一致:-)虽然你的答案不清楚(至少对我来说),所以我认为提及它很有用。