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来测试助手方法。