我被分配了一个单元测试任务的任务,我从未直接使用过JUnit,严格禁止更改包中的代码。这通常没有问题,因为我们的大多数单元测试只是为了功能和输入/输出的一致性,这可以通过运行例程并检查它们的返回值来完成。
但是,偶尔需要检查类中的私有变量,或者直接编辑私有变量以检查某些内部行为。有没有办法获得访问这些,无论是通过JUnit或任何其他方式,为了单元测试而不实际更改原始源包中的任何代码?如果没有,程序员如何在现实世界中处理这个问题,而单位测试人员可能与编码人员不同?
答案 0 :(得分:47)
首先,你现在处于一个不好的位置 - 负责为你最初没有创建的代码编写测试,没有任何改变 - 噩梦!与老板交谈并解释,如果不使其“可测试”,就无法测试代码。为了使代码可测试,您通常会做一些重要的更改;
关于私人变量。你实际上永远不应该这样做。旨在测试私有变量是当前设计出现问题的第一个迹象。私有变量是实现的一部分,测试应该关注行为而不是实现细节。
有时候,私人领域会受到一些吸气者的公共访问。我这样做,但尽量避免(在评论中标记,如'用于测试')。
由于你没有可能改变代码,我没有看到检查私有变量的可能性(我的意思是真实的可能性,而不是像反射黑客等)。
答案 1 :(得分:26)
是的,您可以使用反射来访问私有变量。虽然不是一个好主意。
检查出来:
http://en.wikibooks.org/wiki/Java_Programming/Reflection/Accessing_Private_Features_with_Reflection
答案 2 :(得分:16)
Reflection e.g:
public class PrivateObject {
private String privateString = null;
public PrivateObject(String privateString) {
this.privateString = privateString;
}
}
PrivateObject privateObject = new PrivateObject("The Private Value");
Field privateStringField = PrivateObject.class.
getDeclaredField("privateString");
privateStringField.setAccessible(true);
String fieldValue = (String) privateStringField.get(privateObject);
System.out.println("fieldValue = " + fieldValue);
答案 3 :(得分:3)
尽管存在明显的危险:使用单元测试,您希望测试对象的正确行为 - 这是根据其公共接口定义的。您对对象如何完成此任务不感兴趣 - 这是一个实现细节,对外部不可见。这是OO被发明的原因之一:隐藏了实现细节。所以测试私人成员没有意义。你说你需要100%的覆盖率。如果有一段代码无法通过使用对象的公共接口进行测试,那么这段代码实际上从未被调用过,因此无法测试。删除它。
答案 4 :(得分:1)
这篇文章解决了这个问题(特别是涉及测试):
答案 5 :(得分:0)
我不知道你是否找到了一些特殊的案例代码,要求你对私有字段进行测试。但根据我的经验,你永远不必测试私人物品 - 总是公开的。也许你可以给出一些你需要测试私有的代码的例子吗?
答案 6 :(得分:0)
如果您在单独的文件夹中创建测试类,然后将其添加到构建路径,
然后,您可以通过正确使用包来设置命名空间,使测试类成为被测试类的内部类。这使它可以访问私有字段和方法。
但是不要忘记从发布版本的构建路径中删除该文件夹。