我有一个实用工具方法来查找特定字段的对象的getter方法(使用反射):
public static Method findGetter(final Object object, final String fieldName) {
if( object == null ) {
throw new NullPointerException("object should not be null");
} else if( fieldName == null ) {
throw new NullPointerException("fieldName should not be null");
}
String getterName = getMethodNameForField(GET_PREFIX, fieldName);
Class<?> clazz = object.getClass();
try {
return clazz.getMethod(getterName);
} catch(final NoSuchMethodException e) {
// exception handling omitted
} catch(final SecurityException e) {
// exception handling omitted
}
}
我想编写一个涵盖SecurityException场景的单元测试,但是如何让getMethod抛出SecurityException?
javadoc声明getMethod
将抛出SecurityException
如果存在安全管理器s,则存在以下任何一种情况 条件得到满足:
调用s.checkMemberAccess(this,Member.PUBLIC)拒绝访问该方法
调用者的类加载器与当前类和调用的类加载器不同或是它的祖先 s.checkPackageAccess()拒绝访问此类的包
我宁愿通常触发异常,而不是诉诸于模拟框架。
答案 0 :(得分:11)
System.setSecurityManager(new SecurityManager(){
@Override
public void checkMemberAccess(Class<?> clazz, int which) {
throw new SecurityException("Not allowed")
}
@Override
public void checkPermission(Permission perm) {
// allow resetting the SM
}
});
ClassTest.class.getMethod("foo");
请务必在System.setSecurityManager(null)
块中调用finally
以恢复原始状态。
答案 1 :(得分:0)
至于在常规设置中造成这种情况,很少会出现这种情况。
非公开方法会产生NoSuchMethodException
,因为getMethod
专门只查找公共方法。 getDeclaredMethod
将找到该方法,但允许返回私有/受保护的方法。
唯一可行的方法是,正如javadoc所说,有一个受安全管理器保护的独立包,我猜这只能用未签名的applet或类似的权限来完成。 (我自己从来没有碰到这个,所以我不完全确定)
最好的办法是通过覆盖安全管理器强制为特定方法抛出异常。