在JUNIT中访问对象的非公共方法

在JUNIT中访问对象的非公共方法,junit,Junit,嗨,我是单元测试新手。可以访问私有的方法吗 一个非常简单的例子 ObjectA ---------- File file; private void setupFile (){ //do something file = "C:\file.dat" } 在测试用例中 File sth = ObjectA.setupFile(); assertNotNull(sth); 我无法测试ObjectA.setup()方法中的文件变量是否为null 因为我无法运行ObjectA.set

嗨,我是单元测试新手。可以访问私有的方法吗

一个非常简单的例子

ObjectA 
----------

File file;

private void setupFile (){
  //do something
  file = "C:\file.dat"
}

在测试用例中

File sth = ObjectA.setupFile();
assertNotNull(sth);
我无法测试ObjectA.setup()方法中的文件变量是否为null 因为我无法运行ObjectA.setupFile()

我不确定这样做在单元测试方面是否有意义

那么,编写每个返回sth的方法并将它们设置为公共的,以便进行更简单的单元测试,这是更好的做法吗


提前感谢

如果不一定要将该方法设置为私有,您可以将其设置为包私有(即默认访问),以便在JUnit测试中直接调用它

包私有方法只能在声明它们的包中使用,并且不能成为类API的一部分。通过在方法包的声明上不添加任何修饰符,可以将其声明为私有

下面是一个示例来演示:

public class MyClass() {
 int foo;

 public MyClass() {
  this.foo = 0;
 }

 void notSoComplexCalculationMethod(int a) {
  foo = a * 2;
 }
  //Other methods here . . .
}

public class MyClassTest extends TestCase {
  private MyClass myClass;

  protected void setUp() {
    super.setUp();
    myClass = new MyClass();
  }

  public void testNotSoComplexCalculationMethod() {
   int a = 2;

   assertEquals(4, myClass.notSoComplexCalculationMethod(a));
   //Unit test passes, yay! Now you've tested a package private method.
   }
}

通常,您应该避免更改方法/字段的访问权限以启用测试。如果这样做,那么直接使用该方法的开发人员将面临风险

但是,如果确实需要,那么按照Deco的说法对其进行保护是一个好方法,因此可以从JUnit测试中访问它。如果您这样做,请确保有充分的文件证明这是一种内部使用的方法

一个更好的方法是测试公共方法的行为;您不应该关心类的内部实现细节,所以您应该只测试公共方法。很难从您的代码中分辨出来,但据推测,setupFile()稍后会对其他方法产生影响,因此您可以测试这些影响,而不是测试文件不为null这一事实


外部依赖项(例如对文件系统、环境变量的依赖项)可以在测试中处理,也可以直接注入类中。关于一般原则,请参见我对

的回答,不要为了单元测试而公开私有方法。私有方法将由公共方法调用(如果不是,则应删除它们)。要跟踪正在调用的私有方法,请使用覆盖工具。谢谢您的详细回答。我同意我们不应该为了测试而改变可见性。因此,单元测试更像是测试对象的行为,我提到的目的应该由调试器+编译器来完成。由于我的应用程序很小,不会发布,所以我认为设置它们包可见性会有很大帮助