如何对具有内部私有方法,字段或嵌套类的类进行单元测试(使用xUnit)? 还是通过内部链接 (在C / C ++中为static
)或在私有( 匿名 )名称空间中使其私有化的函数?
仅仅为了能够运行测试而更改方法或函数的访问修饰符似乎很糟糕。
#1楼
过去,我曾使用反射来为Java执行此操作,我认为这是一个很大的错误。
严格来说,你不应该编写单元测试直接测试私有方法。 您应该测试的是该类与其他对象之间的公共合同; 您永远不要直接测试对象的内部。 如果另一个开发人员想要对该类进行小的内部更改,而不影响该类的公共合同,则他/她必须修改您基于反射的测试以确保它可以工作。 如果您在整个项目中重复执行此操作,则单元测试将不再是对代码运行状况的有用衡量,并开始成为开发的障碍和开发团队的烦恼。
我建议做的是使用诸如Cobertura之类的代码覆盖工具,以确保您编写的单元测试以私有方法提供对代码的适当覆盖。 这样,您可以间接测试私有方法的功能,并保持更高的敏捷性。
#2楼
今天,我推出了一个Java库来帮助测试私有方法和字段。 它的设计考虑了Android,但实际上可以用于任何Java项目。
如果您使用私有方法或字段或构造函数获取一些代码,则可以使用BoundBox 。 它确实满足您的需求。 以下是一个测试示例,该示例访问一个Android活动的两个私有字段进行测试:
@UiThreadTest
public void testCompute() {
// Given
boundBoxOfMainActivity = new BoundBoxOfMainActivity(getActivity());
// When
boundBoxOfMainActivity.boundBox_getButtonMain().performClick();
// Then
assertEquals("42", boundBoxOfMainActivity.boundBox_getTextViewMain().getText());
}
BoundBox可以轻松测试私有/受保护的字段,方法和构造函数。 您甚至可以访问被继承隐藏的内容。 实际上,BoundBox破坏了封装。 它将使您能够通过反射访问所有内容, 但在编译时会检查所有内容。
它是测试某些旧代码的理想选择。 小心使用。 ;)
https://github.com/stephanenicolas/boundbox
#3楼
测试私有方法会破坏类的封装,因为每次更改内部实现时,都会破坏客户端代码(在这种情况下为测试)。
因此,请勿测试私有方法。
#4楼
私有方法由公共方法使用。 否则,它们就是无效代码。 这就是为什么要测试公共方法,声明公共方法的预期结果以及由此使用的私有方法的原因。
在私有方法上运行单元测试之前,应通过调试来测试私有方法。
也可以使用测试驱动的开发来调试它们,调试单元测试,直到满足所有声明为止。
我个人认为最好使用TDD创建类。 创建公共方法存根,然后使用预先定义的所有断言生成单元测试,因此在对方法进行编码之前,应确定该方法的预期结果。 这样,您就不会沿着使单元测试断言适合结果的错误道路走下去。 这样,您的课程将变得很健壮,并且在所有单元测试都通过后就可以满足要求。
#5楼
这是我测试私有字段的通用函数:
protected <F> F getPrivateField(String fieldName, Object obj)
throws NoSuchFieldException, IllegalAccessException {
Field field =
obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return (F)field.get(obj);
}