Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将私有成员更改为测试的默认成员_Java_Unit Testing - Fatal编程技术网

Java 将私有成员更改为测试的默认成员

Java 将私有成员更改为测试的默认成员,java,unit-testing,Java,Unit Testing,将私有类成员更改为默认值(包访问)以测试其行为是一个好主意吗?我的意思是,测试用例应该位于测试目录中,但和被测试成员的类位于同一个包中 编辑:你们都说了实话。但是类通常有助手私有方法。这些方法可能很复杂,因此需要进行测试。这太糟糕了——无法测试公共方法以确保私人复杂方法的正确工作。你不这么认为吗?我通常更喜欢以一种对公共API编写测试的方式编写类和测试。因此,基本上我是说,如果您需要访问被测类的私有状态,那么您可能已经在测试中过多地参与了该类的内部工作。不,它不是。因为改变测试对象可能会改变结果

将私有类成员更改为默认值(包访问)以测试其行为是一个好主意吗?我的意思是,测试用例应该位于测试目录中,但和被测试成员的类位于同一个包中


编辑:你们都说了实话。但是类通常有助手私有方法。这些方法可能很复杂,因此需要进行测试。这太糟糕了——无法测试公共方法以确保私人复杂方法的正确工作。你不这么认为吗?

我通常更喜欢以一种对公共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
   }
}

我理解你关于需要测试私有方法的意思,我也明白为什么人们说只测试公共方法。我刚刚遇到了一些遗留代码,其中有许多私有方法,其中一些由公共方法调用,但有些是线程,或由线程调用,它们在构建对象时被启动。由于代码充满了bug,并且没有任何注释,我不得不测试私有代码。 我用这种方法来解决这个问题

   MainObject.cs
    class MainObject
    {
        protected int MethodOne();    // Should have been private.
        ....
    }
    TestMainObject.cs
    class ExposeMainObject : MainObject
    {
        public int MethodOne();
    }
    class TestMainObject
    {
        public void TestOne()
        {
        }
    }

由于测试对象没有发货,我看不出有什么问题,但如果有问题,请告诉我。

测试胜过隐私修改器。实际上,一个方法的可见性“有点太高”导致错误的频率是多少?与未经充分测试的方法引起的错误相比

如果java有一个“朋友”选项,比如C++,那就好了。但是语言上的限制永远不应该成为不测试某些东西的借口

MichaelFeathers在《有效地使用遗留代码》(优秀的书)一书中加入了这场辩论,并指出这可能是一种想要被提取(并拥有公共方法)的子类的味道

在我们的车间(~1M LOC),我们将“private”替换为“/TestScope/”,作为一个指标,表明一个方法应该是有效私有的,但仍然是可测试的


试图通过反思来规避“隐私”是一种气味。这使得测试更难编写、阅读和调试,以保持对隐私的“崇拜”,不管怎样,你都在努力解决这个问题。为什么要麻烦?

如果你想让一个类自己检查,你可以做一些事情,比如收缩类。+1通过测试公共API,你无论如何都在隐式地测试私有API。+1如果你不能通过公共API测试私有方法,请删除它,因为无法访问它。;)谢谢,这是个好主意,但练习不好。不必要的方法会影响增长,这很糟糕。@Michael Z-我知道。与测试私有方法一样糟糕的做法;)如果您不介意更改Visibility,那么就这样做。否则:使用现有的或提供新的可视API来测试助手方法。