将私有成员更改为默认成员进行测试

| 将私有类成员更改为默认(程序包访问)以测试其行为是否是个好主意?我的意思是测试用例应该在测试目录中,但与受测成员的类位于同一软件包中。 编辑:你们都说出了真实。但是类通常具有辅助私有方法。这些方法可能很复杂,因此需要进行测试。那就太糟糕了-测试公共方法以确保正确处理私有复杂方法。你不这样认为吗?     
已邀请:
我通常更喜欢以对公共API编写测试有意义的方式编写类和测试。因此,基本上,我是说如果您需要访问被测类的私有状态,那么您可能已经在测试中涉及该类的内部。     
不,不是。因为更改测试对象可能会更改结果。如果您确实需要在测试期间调用私有成员或方法,则添加访问器更为安全。这仍然会改变类别,但风险较低。例:
private void method() { /* ... */ }

// For testing purpose only, remove for production
@Deprecated  // just another way to create awareness ;)
void testMethod() {
   method();
}
好的-如果需要测试私有方法,则可以采用另一种解决方案:可以使用反射和实例化API调用任何方法。 假设,我们有:
public class SomeClass {
  private Object helper(String s, String t) { /* ... +/ }
}
然后我们可以像测试
@Test public void testHelper() {
   try {
     SomeClass some = new SomeClass();
     Method helperMethod = some.getClass().getDeclaredMethod(\"helper\", String.class, String,class);
     helperMethod.setAccessible(true);
     Object result = helperMethod.invoke(some, \"s\", \"t\");
     // do some assert...

   catch(Exception e) {
     // TODO - proper exception handling
   }
}
    
我了解您需要测试私有方法的意思,并且我也明白了为什么人们只说测试公共方法。我刚刚遇到了一些遗留代码,这些遗留代码具有许多私有方法,其中一些被公共方法调用,但是一些是线程或被线程调用,它们在构造对象时启动。由于代码到处都是错误,并且缺少任何注释,因此我不得不测试私有代码。 我已经使用这种方法解决了这个问题。
   MainObject.cs
    class MainObject
    {
        protected int MethodOne();    // Should have been private.
        ....
    }
    TestMainObject.cs
    class ExposeMainObject : MainObject
    {
        public int MethodOne();
    }
    class TestMainObject
    {
        public void TestOne()
        {
        }
    }
由于未交付测试对象,所以看不到问题,但是如果有请告诉我。     
测试胜过隐私修改器。确实,某个方法的可见度“过高”导致的bug多久发生一次?与未经过完全测试的方法引起的错误相比? 如果Java具有\“ friend \”选项(如C ++),那就太好了。但是语言的限制绝不能成为不测试的借口。 迈克尔·费瑟斯(Michael Feathers)在“有效地使用旧版代码”(出色的书)中对此辩论进行了评论,并暗示这可能是想要提取(并具有公共方法)的子类的味道。 在我们的商店(〜1M LOC)中,我们用\'/ TestScope / \'代替\'private \',以指示方法应有效地私有,但仍可测试。 试图通过反射来规避“私人”是恕我直言。为了保持“迷信”的私密性,使测试变得更加难以编写,阅读和调试,而无论如何您都在努力。何必?     

要回复问题请先登录注册