如何测试具有私有方法、字段或内部类的类? [英] How do I test a class that has private methods, fields or inner classes?
问题描述
如何使用 JUnit 测试具有内部私有方法、字段或嵌套类的类?
为了能够运行测试而更改方法的访问修饰符似乎很糟糕.
更新:
大约 10 年后,测试私有方法或任何无法访问的成员的最佳方法可能是通过 Manifold 框架.
@Jailbreak Foo foo = new Foo();//直接、*类型安全* 访问*所有* foo 的成员foo.privateMethod(x, y, z);foo.privateField = 值;
这样你的代码就保持了类型安全和可读性.没有设计妥协,没有为了测试而过度暴露方法和领域.
如果您有一些遗留的 Java 应用程序,并且不允许您更改方法的可见性,那么测试私有方法的最佳方法是使用 反射.
在内部,我们使用助手来获取/设置 private
和 private static
变量以及调用 private
和 private static
方法.以下模式将让您几乎可以执行与私有方法和字段相关的任何事情.当然,你不能通过反射改变private static final
变量.
Method method = TargetClass.getDeclaredMethod(methodName, argClasses);method.setAccessible(true);返回 method.invoke(targetObject, argObjects);
对于字段:
Field field = TargetClass.getDeclaredField(fieldName);field.setAccessible(true);field.set(object, value);
<小时><块引用>
注意事项:
1. TargetClass.getDeclaredMethod(methodName, argClasses)
让您查看 private
方法.同样的事情适用于getDeclaredField
.
2. setAccessible(true)
需要玩弄私有.
How do I use JUnit to test a class that has internal private methods, fields or nested classes?
It seems bad to change the access modifier for a method just to be able to run a test.
Update:
Some 10 years later perhaps the best way to test a private method, or any inaccessible member, is via
@Jailbreak
from the Manifold framework.@Jailbreak Foo foo = new Foo(); // Direct, *type-safe* access to *all* foo's members foo.privateMethod(x, y, z); foo.privateField = value;
This way your code remains type-safe and readable. No design compromises, no overexposing methods and fields for the sake of tests.
If you have somewhat of a legacy Java application, and you're not allowed to change the visibility of your methods, the best way to test private methods is to use reflection.
Internally we're using helpers to get/set private
and private static
variables as well as invoke private
and private static
methods. The following patterns will let you do pretty much anything related to the private methods and fields. Of course, you can't change private static final
variables through reflection.
Method method = TargetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);
And for fields:
Field field = TargetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
Notes:
1.TargetClass.getDeclaredMethod(methodName, argClasses)
lets you look intoprivate
methods. The same thing applies forgetDeclaredField
.
2. ThesetAccessible(true)
is required to play around with privates.
这篇关于如何测试具有私有方法、字段或内部类的类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!